Setup

Load Packages

##Install Packages if Needed
if (!require("ggplot2")) install.packages("ggplot2")
Loading required package: ggplot2
if (!require("effectsize")) install.packages("effectsize")
Loading required package: effectsize
if (!require("emmeans")) install.packages("emmeans")
Loading required package: emmeans
if (!require("dplyr")) install.packages("dplyr")
Loading required package: dplyr

Attaching package: ‘dplyr’

The following objects are masked from ‘package:stats’:

    filter, lag

The following objects are masked from ‘package:base’:

    intersect, setdiff, setequal, union
if (!require("tidyr")) install.packages("tidyr")
Loading required package: tidyr
if (!require("Rmisc")) install.packages("Rmisc")
Loading required package: Rmisc
Loading required package: lattice
Loading required package: plyr
----------------------------------------------------------------------------------
You have loaded plyr after dplyr - this is likely to cause problems.
If you need functions from both plyr and dplyr, please load plyr first, then dplyr:
library(plyr); library(dplyr)
----------------------------------------------------------------------------------

Attaching package: ‘plyr’

The following objects are masked from ‘package:dplyr’:

    arrange, count, desc, failwith, id, mutate, rename, summarise,
    summarize
if (!require("ggpubr")) install.packages("ggpubr")
Loading required package: ggpubr

Attaching package: ‘ggpubr’

The following object is masked from ‘package:plyr’:

    mutate
if (!require("cowplot")) install.packages("cowplot")
Loading required package: cowplot

Attaching package: ‘cowplot’

The following object is masked from ‘package:ggpubr’:

    get_legend
if (!require("gridGraphics")) install.packages("gridGraphics")
Loading required package: gridGraphics
Warning: package ‘gridGraphics’ was built under R version 4.3.2Loading required package: grid
if (!require("tidyr")) install.packages("tidyr")

##Load Packages
library(ggplot2) #Required for plotting
library(effectsize) #Required for eta_squared effect sizes
library(emmeans) #Required for pairwise comparisons
library(dplyr) #Required to seperate columns in dataframe
library(tidyr) #Required for data organization
library(Rmisc) #Required for summarySE for summary statistics
library(ggpubr) #Required for adding pairwise p-values to plots with stat_pvalue_manual 
library(cowplot) #Required for arranging ggplots 
library(gridGraphics) #Required for adding labels to arranged plots
library(tidyr) #Required for reshaping datafrom from a wide to long format.

Note: Run “Graphing Parameters” section from 01_ExperimentalSetup.R file

Load and Organize Data

Note: Full Data with Bleaching Metrics and Color Scores created in 04_Models.R file

#Load Data
FullData<-read.csv("Outputs/FullData.csv", header=TRUE)


#Set factor variables 
FullData$TimeP<-factor(FullData$TimeP, levels=c("W2", "M1", "M4"), ordered=TRUE)
FullData$Site<-factor(FullData$Site, levels=c("KL", "SS"), ordered=TRUE)
FullData$Genotype<-factor(FullData$Genotype, levels=c("AC10", "AC12", "AC8"), ordered=TRUE)
FullData$Treatment<-factor(FullData$Treatment, levels=c("Control", "Heat"), ordered=TRUE)
FullData$Treat<-factor(FullData$Treat, levels=c("C", "H"), ordered=TRUE)
FullData$Seas<-factor(FullData$Seas, levels=c("Summer1", "Summer2", "Winter"), ordered=TRUE)

Percent Retention

Subset Thermal Assay Data by Treatment

##Control
FullData_C<-subset(FullData, Treat=="C")

##Heated
FullData_H<-subset(FullData, Treat=="H")

Calculate Percent Retention

Calculating retention as proportion remaining relative to corresponding control levels (0-1) for each site and genotype at each timepoint.

##Calculate averages for Control Treatment for each Site, Genotype, Timepoint, and Season
names(FullData_C)
 [1] "ID"          "RandN"       "TimeP"       "Site"        "Genotype"   
 [6] "Treat"       "Treatment"   "Seas"        "Set"         "Score_Full" 
[11] "Score_TP"    "SA_cm2"      "Chl_ug.cm2"  "Sym10.6_cm2"
FullData_C.a<-aggregate(FullData_C[,c(10:11, 13:14)], list(FullData_C$Site, FullData_C$Genotype, FullData_C$TimeP, FullData_C$Seas), mean, na.action = na.omit)
names(FullData_C.a)[1:4]<-c("Site", "Genotype", "TimeP", "Seas")
names(FullData_C.a)[5:8]<-paste(names(FullData_C)[c(10:11, 13:14)], "C", sep="_")

##Merge Control Averages with Heated Samples
#Merges by Site, Genotype, Timepoint, and Season
TolData<-merge(FullData_H, FullData_C.a, all.x=TRUE )

##Calculate Proportion Retained for each Bleaching Metric relative to Control
TolData$Score_Full.prop<-round((TolData$Score_Full/TolData$Score_Full_C), 4)
TolData$Score_TP.prop<-round((TolData$Score_TP/TolData$Score_TP_C), 4)
TolData$Chl.prop<-round((TolData$Chl_ug.cm2/TolData$Chl_ug.cm2_C), 4)
TolData$Sym.prop<-round((TolData$Sym10.6_cm2/TolData$Sym10.6_cm2_C), 4)

##Set values >1 to 1
TolData$Score_Full.prop[which(TolData$Score_Full.prop>1)]<-1.0000
TolData$Score_TP.prop[which(TolData$Score_TP.prop>1)]<-1.0000
TolData$Chl.prop[which(TolData$Chl.prop>1)]<-1.0000
TolData$Sym.prop[which(TolData$Sym.prop>1)]<-1.0000

##Create Site and Genotype Variable
TolData$Site.Geno<-paste(TolData$Site, TolData$Genotype, sep="_")

Subset by Timepoint

TolData_W2<-subset(TolData, TimeP=="W2")
TolData_M1<-subset(TolData, TimeP=="M1")
TolData_M4<-subset(TolData, TimeP=="M4")

Thermal Tolerance Chlorophyll

Full Set

Run Model

##Check normality
hist(TolData$Chl.prop)

shapiro.test(TolData$Chl.prop)

    Shapiro-Wilk normality test

data:  TolData$Chl.prop
W = 0.97395, p-value = 0.165
#Normal

##Model as a function of Site and Genotype and Timepoint
Tol_Chl_lm<-lm(Chl.prop~Site+Genotype+TimeP+ Site:Genotype + Site:TimeP + Genotype:TimeP, data=TolData)

Check Residuals

##Check Normality of Residuals
#Distribution 
plot(density(resid(Tol_Chl_lm)))


#Q-Q plot
qqnorm(resid(Tol_Chl_lm)); qqline(resid(Tol_Chl_lm))


##Check Variance of Residuals across Fitted Values
plot(fitted(Tol_Chl_lm), resid(Tol_Chl_lm))

Model Results

#Model Results
summary(Tol_Chl_lm)

Call:
lm(formula = Chl.prop ~ Site + Genotype + TimeP + Site:Genotype + 
    Site:TimeP + Genotype:TimeP, data = TolData)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.127060 -0.031006 -0.004219  0.036829  0.097690 

Coefficients:
                     Estimate Std. Error t value Pr(>|t|)    
(Intercept)         0.2100753  0.0065828  31.913  < 2e-16 ***
Site.L             -0.0093229  0.0092942  -1.003 0.320289    
Genotype.L         -0.0980285  0.0111500  -8.792 5.31e-12 ***
Genotype.Q         -0.0467859  0.0116301  -4.023 0.000180 ***
TimeP.L             0.0638187  0.0112994   5.648 6.22e-07 ***
TimeP.Q             0.0464233  0.0115033   4.036 0.000173 ***
Site.L:Genotype.L   0.0003917  0.0157685   0.025 0.980272    
Site.L:Genotype.Q   0.0592529  0.0164183   3.609 0.000673 ***
Site.L:TimeP.L     -0.0528050  0.0159798  -3.304 0.001694 ** 
Site.L:TimeP.Q     -0.0236749  0.0161894  -1.462 0.149435    
Genotype.L:TimeP.L  0.0406686  0.0194339   2.093 0.041093 *  
Genotype.Q:TimeP.L -0.0627603  0.0196595  -3.192 0.002354 ** 
Genotype.L:TimeP.Q  0.0800244  0.0191901   4.170 0.000111 ***
Genotype.Q:TimeP.Q -0.1328570  0.0206170  -6.444 3.28e-08 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.05393 on 54 degrees of freedom
  (1 observation deleted due to missingness)
Multiple R-squared:  0.8229,    Adjusted R-squared:  0.7803 
F-statistic:  19.3 on 13 and 54 DF,  p-value: 8.612e-16
anova(Tol_Chl_lm)
Analysis of Variance Table

Response: Chl.prop
               Df   Sum Sq  Mean Sq F value    Pr(>F)    
Site            1 0.001563 0.001563  0.5375  0.466633    
Genotype        2 0.297307 0.148654 51.1117 3.495e-13 ***
TimeP           2 0.132285 0.066142 22.7418 6.845e-08 ***
Site:Genotype   2 0.041114 0.020557  7.0681  0.001877 ** 
Site:TimeP      2 0.038643 0.019322  6.6434  0.002634 ** 
Genotype:TimeP  4 0.218951 0.054738 18.8205 9.691e-10 ***
Residuals      54 0.157054 0.002908                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Effect Size of Predictors
eta_squared(Tol_Chl_lm, partial=FALSE)
# Effect Size for ANOVA (Type I)

Parameter      |     Eta2 |       95% CI
----------------------------------------
Site           | 1.76e-03 | [0.00, 1.00]
Genotype       |     0.34 | [0.16, 1.00]
TimeP          |     0.15 | [0.02, 1.00]
Site:Genotype  |     0.05 | [0.00, 1.00]
Site:TimeP     |     0.04 | [0.00, 1.00]
Genotype:TimeP |     0.25 | [0.06, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_Chl_lm.res<-data.frame(anova(Tol_Chl_lm))
Tol_Chl_lm.res$Predictor<-rownames(Tol_Chl_lm.res)
Tol_Chl_lm.res$EtaSq<-c(eta_squared(Tol_Chl_lm, partial=FALSE)$Eta2, NA)
Tol_Chl_lm.res$Response<-rep("Chlorophyll", nrow(Tol_Chl_lm.res))
Tol_Chl_lm.res<-Tol_Chl_lm.res %>% dplyr::rename( p.value = "Pr..F.", DF= "Df")

Strong influence of Timepoint, including interactions with main variables of interest, Site and Genotype. Will analyze each Timepoint individually.

Chl Summer 1 Timepoint W2

Run Model

##Check normality
hist(TolData_W2$Chl.prop)

shapiro.test(TolData_W2$Chl.prop)

    Shapiro-Wilk normality test

data:  TolData_W2$Chl.prop
W = 0.98407, p-value = 0.9671
#Normal

##Model as a function of Site and Genotype
Tol_Chl_W2_lm<-lm(Chl.prop~Site+Genotype+Site:Genotype, data=TolData_W2)

Check Residuals

##Check Normality of Residuals
#Distribution 
plot(density(resid(Tol_Chl_W2_lm)))


#Q-Q plot
qqnorm(resid(Tol_Chl_W2_lm)); qqline(resid(Tol_Chl_W2_lm))


##Check Variance of Residuals across Fitted Values
plot(fitted(Tol_Chl_W2_lm), resid(Tol_Chl_W2_lm))

Model Results

Overall

#Model Results
summary(Tol_Chl_W2_lm)

Call:
lm(formula = Chl.prop ~ Site + Genotype + Site:Genotype, data = TolData_W2)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.089900 -0.031587 -0.008183  0.038881  0.103550 

Coefficients:
                    Estimate Std. Error t value Pr(>|t|)    
(Intercept)        0.1842264  0.0119450  15.423 5.03e-11 ***
Site.L             0.0188110  0.0168928   1.114 0.281921    
Genotype.L        -0.0947759  0.0204291  -4.639 0.000273 ***
Genotype.Q        -0.0585870  0.0209464  -2.797 0.012921 *  
Site.L:Genotype.L -0.0002833  0.0288911  -0.010 0.992297    
Site.L:Genotype.Q  0.0366569  0.0296227   1.237 0.233769    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.05552 on 16 degrees of freedom
  (1 observation deleted due to missingness)
Multiple R-squared:  0.6758,    Adjusted R-squared:  0.5745 
F-statistic: 6.671 on 5 and 16 DF,  p-value: 0.001551
anova(Tol_Chl_W2_lm)
Analysis of Variance Table

Response: Chl.prop
              Df   Sum Sq  Mean Sq F value   Pr(>F)    
Site           1 0.005580 0.005580  1.8106 0.197195    
Genotype       2 0.092482 0.046241 15.0038 0.000214 ***
Site:Genotype  2 0.004732 0.002366  0.7677 0.480448    
Residuals     16 0.049311 0.003082                     
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Effect Size of Predictors
eta_squared(Tol_Chl_W2_lm, partial=FALSE)
# Effect Size for ANOVA (Type I)

Parameter     | Eta2 |       95% CI
-----------------------------------
Site          | 0.04 | [0.00, 1.00]
Genotype      | 0.61 | [0.29, 1.00]
Site:Genotype | 0.03 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_Chl_W2_lm.res<-data.frame(anova(Tol_Chl_W2_lm))
Tol_Chl_W2_lm.res$Predictor<-rownames(Tol_Chl_W2_lm.res)
Tol_Chl_W2_lm.res$EtaSq<-c(eta_squared(Tol_Chl_W2_lm, partial=FALSE)$Eta2, NA)
Tol_Chl_W2_lm.res$Response<-rep("Chlorophyll", nrow(Tol_Chl_W2_lm.res))
Tol_Chl_W2_lm.res$TimeP<-rep("W2", nrow(Tol_Chl_W2_lm.res))
Tol_Chl_W2_lm.res<-Tol_Chl_W2_lm.res %>% dplyr::rename( p.value = "Pr..F.", DF= "Df")

Significant effect of Genotype. Still checking Site*Genotype for comparability across Timepoints.

Pairwise

#Pairwise comparisons across:

#Genotypes within Sites
emmeans(Tol_Chl_W2_lm, pairwise~Genotype | Site)
$emmeans
Site = KL:
 Genotype emmean     SE df lower.CL upper.CL
 AC10     0.2033 0.0278 16   0.1445    0.262
 AC12     0.2399 0.0278 16   0.1811    0.299
 AC8      0.0696 0.0278 16   0.0107    0.128

Site = SS:
 Genotype emmean     SE df lower.CL upper.CL
 AC10     0.2514 0.0278 16   0.1925    0.310
 AC12     0.2242 0.0321 16   0.1563    0.292
 AC8      0.1170 0.0321 16   0.0491    0.185

Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12  -0.0366 0.0393 16  -0.933  0.6280
 AC10 - AC8    0.1338 0.0393 16   3.407  0.0095
 AC12 - AC8    0.1704 0.0393 16   4.340  0.0014

Site = SS:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12   0.0272 0.0424 16   0.640  0.8003
 AC10 - AC8    0.1343 0.0424 16   3.168  0.0156
 AC12 - AC8    0.1072 0.0453 16   2.364  0.0753

P value adjustment: tukey method for comparing a family of 3 estimates 
#Sites within Genotypes
emmeans(Tol_Chl_W2_lm, pairwise~Site | Genotype)
$emmeans
Genotype = AC10:
 Site emmean     SE df lower.CL upper.CL
 KL   0.2033 0.0278 16   0.1445    0.262
 SS   0.2514 0.0278 16   0.1925    0.310

Genotype = AC12:
 Site emmean     SE df lower.CL upper.CL
 KL   0.2399 0.0278 16   0.1811    0.299
 SS   0.2242 0.0321 16   0.1563    0.292

Genotype = AC8:
 Site emmean     SE df lower.CL upper.CL
 KL   0.0696 0.0278 16   0.0107    0.128
 SS   0.1170 0.0321 16   0.0491    0.185

Confidence level used: 0.95 

$contrasts
Genotype = AC10:
 contrast estimate     SE df t.ratio p.value
 KL - SS   -0.0481 0.0393 16  -1.224  0.2387

Genotype = AC12:
 contrast estimate     SE df t.ratio p.value
 KL - SS    0.0157 0.0424 16   0.371  0.7156

Genotype = AC8:
 contrast estimate     SE df t.ratio p.value
 KL - SS   -0.0475 0.0424 16  -1.120  0.2793
##Save p-values

#Genotypes within Sites
Tol_Chl_W2_lm.geno<-data.frame(emmeans(Tol_Chl_W2_lm, pairwise~Genotype | Site)$contrasts)
Tol_Chl_W2_lm.geno<-Tol_Chl_W2_lm.geno %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_Chl_W2_lm.geno$group1<-paste(Tol_Chl_W2_lm.geno$Site, Tol_Chl_W2_lm.geno$group1, sep="_")
Tol_Chl_W2_lm.geno$group2<-paste(Tol_Chl_W2_lm.geno$Site, Tol_Chl_W2_lm.geno$group2, sep="_")

#Sites within Genotypes
Tol_Chl_W2_lm.site<-data.frame(emmeans(Tol_Chl_W2_lm, pairwise~Site | Genotype)$contrasts)
Tol_Chl_W2_lm.site<-Tol_Chl_W2_lm.site %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_Chl_W2_lm.site$group1<-paste(Tol_Chl_W2_lm.site$group1, Tol_Chl_W2_lm.site$Genotype, sep="_")
Tol_Chl_W2_lm.site$group2<-paste(Tol_Chl_W2_lm.site$group2, Tol_Chl_W2_lm.site$Genotype, sep="_")

#Full list of p-values
Tol_Chl_W2_lm.p<-rbind(Tol_Chl_W2_lm.geno[,c(1:2,4:8)], Tol_Chl_W2_lm.site[,c(1:2,4:8)])
Tol_Chl_W2_lm.p<-Tol_Chl_W2_lm.p %>% dplyr::rename( p = p.value)

#Add Significance Levels
Tol_Chl_W2_lm.p$Sig<-ifelse(Tol_Chl_W2_lm.p$p<0.001, "***", ifelse(Tol_Chl_W2_lm.p$p<0.01, "**", ifelse(Tol_Chl_W2_lm.p$p<0.05, "*", NA)))

#Specify Response and Timepoint
Tol_Chl_W2_lm.p$Response<-rep("Chlorophyll", nrow(Tol_Chl_W2_lm.p))
Tol_Chl_W2_lm.p$TimeP<-rep("W2", nrow(Tol_Chl_W2_lm.p))

Plot Retention by Site and Genotype

##Summary statistics by Site and Genotype
Tol_Chl_W2_SG<-summarySE(TolData_W2, measurevar="Chl.prop", groupvars=c("Site.Geno", "Site", "Genotype"), na.rm=TRUE)

##Plot Average Retention across Treatments
Tol_Chl_W2_SG.plot<-ggplot(Tol_Chl_W2_SG, aes(x=Site.Geno, y=Chl.prop, colour=Genotype)) + 
  geom_errorbar(aes(ymin=Chl.prop-se, ymax=Chl.prop+se), width=cap.sz, linewidth=bar.sz)+
  geom_point(size=point.sz)+ 
   ggtitle("Chlorophyll Retention")+
  theme_classic()+
  theme( axis.title.x = element_text(size = axis.title.sz), 
         axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"),
        axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"),
        legend.position="bottom", 
        legend.direction="horizontal",
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="Proportion Retained")+
  ylim(0, 1)+ 
  scale_x_discrete(labels=c("","Klein","","","Something Special",""))+
  scale_color_manual(values = Geno.colors.o)+ 
  stat_pvalue_manual(data=Tol_Chl_W2_lm.p,  y.position=0.4, step.increase=0.25, label="Sig", hide.ns=TRUE); Tol_Chl_W2_SG.plot

Chl Summer 2 Timepoint M1

Run Model

##Check normality
hist(TolData_M1$Chl.prop)

shapiro.test(TolData_M1$Chl.prop)

    Shapiro-Wilk normality test

data:  TolData_M1$Chl.prop
W = 0.9306, p-value = 0.1263
#Normal

##Model as a function of Site and Genotype
Tol_Chl_M1_lm<-lm(Chl.prop~Site+Genotype+Site:Genotype, data=TolData_M1)

Check Residuals

##Check Normality of Residuals
#Distribution 
plot(density(resid(Tol_Chl_M1_lm)))


#Q-Q plot
qqnorm(resid(Tol_Chl_M1_lm)); qqline(resid(Tol_Chl_M1_lm))


##Check Variance of Residuals across Fitted Values
plot(fitted(Tol_Chl_M1_lm), resid(Tol_Chl_M1_lm))

Model Results

Overall

#Model Results
summary(Tol_Chl_M1_lm)

Call:
lm(formula = Chl.prop ~ Site + Genotype + Site:Genotype, data = TolData_M1)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.107050 -0.034575  0.003479  0.025531  0.088050 

Coefficients:
                  Estimate Std. Error t value Pr(>|t|)    
(Intercept)        0.17217    0.01178  14.619 1.12e-10 ***
Site.L             0.01036    0.01666   0.622   0.5428    
Genotype.L        -0.16337    0.01935  -8.442 2.74e-07 ***
Genotype.Q         0.06169    0.02139   2.883   0.0108 *  
Site.L:Genotype.L  0.03819    0.02737   1.395   0.1820    
Site.L:Genotype.Q  0.05454    0.03026   1.803   0.0903 .  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.05474 on 16 degrees of freedom
Multiple R-squared:  0.8424,    Adjusted R-squared:  0.7932 
F-statistic: 17.11 on 5 and 16 DF,  p-value: 6.411e-06
anova(Tol_Chl_M1_lm)
Analysis of Variance Table

Response: Chl.prop
              Df   Sum Sq  Mean Sq F value    Pr(>F)    
Site           1 0.002283 0.002283  0.7619    0.3956    
Genotype       2 0.238424 0.119212 39.7888 6.168e-07 ***
Site:Genotype  2 0.015569 0.007785  2.5982    0.1054    
Residuals     16 0.047938 0.002996                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Effect Size of Predictors
eta_squared(Tol_Chl_M1_lm, partial=FALSE)
# Effect Size for ANOVA (Type I)

Parameter     |     Eta2 |       95% CI
---------------------------------------
Site          | 7.50e-03 | [0.00, 1.00]
Genotype      |     0.78 | [0.58, 1.00]
Site:Genotype |     0.05 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_Chl_M1_lm.res<-data.frame(anova(Tol_Chl_M1_lm))
Tol_Chl_M1_lm.res$Predictor<-rownames(Tol_Chl_M1_lm.res)
Tol_Chl_M1_lm.res$EtaSq<-c(eta_squared(Tol_Chl_M1_lm, partial=FALSE)$Eta2, NA)
Tol_Chl_M1_lm.res$Response<-rep("Chlorophyll", nrow(Tol_Chl_M1_lm.res))
Tol_Chl_M1_lm.res$TimeP<-rep("M1", nrow(Tol_Chl_M1_lm.res))
Tol_Chl_M1_lm.res<-Tol_Chl_M1_lm.res %>% dplyr::rename( p.value = "Pr..F.", DF= "Df")

Significant effect of Genotype. Still checking Site*Genotype for comparability across Timepoints.

Pairwise

#Pairwise comparisons across:

#Genotypes within Sites
emmeans(Tol_Chl_M1_lm, pairwise~Genotype | Site)
$emmeans
Site = KL:
 Genotype emmean     SE df lower.CL upper.CL
 AC10     0.3089 0.0274 16   0.2509   0.3669
 AC12     0.1460 0.0316 16   0.0790   0.2130
 AC8      0.0397 0.0274 16  -0.0183   0.0977

Site = SS:
 Genotype emmean     SE df lower.CL upper.CL
 AC10     0.3169 0.0274 16   0.2588   0.3749
 AC12     0.0976 0.0316 16   0.0306   0.1646
 AC8      0.1240 0.0274 16   0.0660   0.1820

Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12   0.1629 0.0418 16   3.897  0.0035
 AC10 - AC8    0.2692 0.0387 16   6.956  <.0001
 AC12 - AC8    0.1063 0.0418 16   2.543  0.0538

Site = SS:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12   0.2192 0.0418 16   5.244  0.0002
 AC10 - AC8    0.1928 0.0387 16   4.983  0.0004
 AC12 - AC8   -0.0264 0.0418 16  -0.631  0.8056

P value adjustment: tukey method for comparing a family of 3 estimates 
#Sites within Genotypes
emmeans(Tol_Chl_M1_lm, pairwise~Site | Genotype)
$emmeans
Genotype = AC10:
 Site emmean     SE df lower.CL upper.CL
 KL   0.3089 0.0274 16   0.2509   0.3669
 SS   0.3169 0.0274 16   0.2588   0.3749

Genotype = AC12:
 Site emmean     SE df lower.CL upper.CL
 KL   0.1460 0.0316 16   0.0790   0.2130
 SS   0.0976 0.0316 16   0.0306   0.1646

Genotype = AC8:
 Site emmean     SE df lower.CL upper.CL
 KL   0.0397 0.0274 16  -0.0183   0.0977
 SS   0.1240 0.0274 16   0.0660   0.1820

Confidence level used: 0.95 

$contrasts
Genotype = AC10:
 contrast estimate     SE df t.ratio p.value
 KL - SS  -0.00795 0.0387 16  -0.205  0.8398

Genotype = AC12:
 contrast estimate     SE df t.ratio p.value
 KL - SS   0.04833 0.0447 16   1.081  0.2955

Genotype = AC8:
 contrast estimate     SE df t.ratio p.value
 KL - SS  -0.08432 0.0387 16  -2.179  0.0447
##Save p-values

#Genotypes within Sites
Tol_Chl_M1_lm.geno<-data.frame(emmeans(Tol_Chl_M1_lm, pairwise~Genotype | Site)$contrasts)
Tol_Chl_M1_lm.geno<-Tol_Chl_M1_lm.geno %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_Chl_M1_lm.geno$group1<-paste(Tol_Chl_M1_lm.geno$Site, Tol_Chl_M1_lm.geno$group1, sep="_")
Tol_Chl_M1_lm.geno$group2<-paste(Tol_Chl_M1_lm.geno$Site, Tol_Chl_M1_lm.geno$group2, sep="_")

#Sites within Genotypes
Tol_Chl_M1_lm.site<-data.frame(emmeans(Tol_Chl_M1_lm, pairwise~Site | Genotype)$contrasts)
Tol_Chl_M1_lm.site<-Tol_Chl_M1_lm.site %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_Chl_M1_lm.site$group1<-paste(Tol_Chl_M1_lm.site$group1, Tol_Chl_M1_lm.site$Genotype, sep="_")
Tol_Chl_M1_lm.site$group2<-paste(Tol_Chl_M1_lm.site$group2, Tol_Chl_M1_lm.site$Genotype, sep="_")

#Full list of p-values
Tol_Chl_M1_lm.p<-rbind(Tol_Chl_M1_lm.geno[,c(1:2,4:8)], Tol_Chl_M1_lm.site[,c(1:2,4:8)])
Tol_Chl_M1_lm.p<-Tol_Chl_M1_lm.p %>% dplyr::rename( p = p.value)

#Add Significance Levels
Tol_Chl_M1_lm.p$Sig<-ifelse(Tol_Chl_M1_lm.p$p<0.001, "***", ifelse(Tol_Chl_M1_lm.p$p<0.01, "**", ifelse(Tol_Chl_M1_lm.p$p<0.05, "*", NA)))

#Specify Response and Timepoint
Tol_Chl_M1_lm.p$Response<-rep("Chlorophyll", nrow(Tol_Chl_M1_lm.p))
Tol_Chl_M1_lm.p$TimeP<-rep("M1", nrow(Tol_Chl_M1_lm.p))

Plot Retention by Site and Genotype

##Summary statistics by Site and Genotype
Tol_Chl_M1_SG<-summarySE(TolData_M1, measurevar="Chl.prop", groupvars=c("Site.Geno", "Site", "Genotype"), na.rm=TRUE)

##Plot Average Retention across Treatments
Tol_Chl_M1_SG.plot<-ggplot(Tol_Chl_M1_SG, aes(x=Site.Geno, y=Chl.prop, colour=Genotype)) + 
  geom_errorbar(aes(ymin=Chl.prop-se, ymax=Chl.prop+se), width=cap.sz, linewidth=bar.sz)+
  geom_point(size=point.sz)+ 
   ggtitle("Chlorophyll Retention")+
  theme_classic()+
  theme( axis.title.x = element_text(size = axis.title.sz), 
         axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"),
        axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"),
        legend.position="bottom", 
        legend.direction="horizontal",
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="Proportion Retained")+
  ylim(0, 1)+ 
  scale_x_discrete(labels=c("","Klein","","","Something Special",""))+
  scale_color_manual(values = Geno.colors.o)+ 
  stat_pvalue_manual(data=Tol_Chl_M1_lm.p,  y.position=0.4, step.increase=0.25, label="Sig", hide.ns=TRUE); Tol_Chl_M1_SG.plot

Chl Winter Timepoint M4

Run Model

##Check normality
hist(TolData_M4$Chl.prop)

shapiro.test(TolData_M4$Chl.prop)

    Shapiro-Wilk normality test

data:  TolData_M4$Chl.prop
W = 0.91299, p-value = 0.04096
#Not Normal

##Try log+1 transformation
hist(log(TolData_M4$Chl.prop+1))

shapiro.test(log(TolData_M4$Chl.prop+1))

    Shapiro-Wilk normality test

data:  log(TolData_M4$Chl.prop + 1)
W = 0.93102, p-value = 0.1028
#Normal

##Model as a function of Site and Genotype
##Model with log transformation
Tol_Chl_M4_lm<-lm(log(Chl.prop+1)~Site+Genotype+Site:Genotype, data=TolData_M4)

Check Residuals

##Check Normality of Residuals
#Distribution 
plot(density(resid(Tol_Chl_M4_lm)))


#Q-Q plot
qqnorm(resid(Tol_Chl_M4_lm)); qqline(resid(Tol_Chl_M4_lm))


##Check Variance of Residuals across Fitted Values
plot(fitted(Tol_Chl_M4_lm), resid(Tol_Chl_M4_lm))

Model Results

Overall

#Model Results
summary(Tol_Chl_M4_lm)

Call:
lm(formula = log(Chl.prop + 1) ~ Site + Genotype + Site:Genotype, 
    data = TolData_M4)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.062753 -0.025900 -0.004896  0.017009  0.065759 

Coefficients:
                  Estimate Std. Error t value Pr(>|t|)    
(Intercept)        0.23863    0.00807  29.568  < 2e-16 ***
Site.L            -0.04272    0.01141  -3.743  0.00149 ** 
Genotype.L        -0.03027    0.01398  -2.166  0.04400 *  
Genotype.Q        -0.11052    0.01398  -7.907  2.9e-07 ***
Site.L:Genotype.L -0.03189    0.01977  -1.613  0.12415    
Site.L:Genotype.Q  0.05753    0.01977   2.910  0.00934 ** 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.03954 on 18 degrees of freedom
Multiple R-squared:  0.8368,    Adjusted R-squared:  0.7915 
F-statistic: 18.46 on 5 and 18 DF,  p-value: 1.598e-06
anova(Tol_Chl_M4_lm)
Analysis of Variance Table

Response: log(Chl.prop + 1)
              Df   Sum Sq  Mean Sq F value    Pr(>F)    
Site           1 0.021901 0.021901 14.0102  0.001489 ** 
Genotype       2 0.105056 0.052528 33.6031 8.379e-07 ***
Site:Genotype  2 0.017304 0.008652  5.5349  0.013381 *  
Residuals     18 0.028137 0.001563                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Effect Size of Predictors
eta_squared(Tol_Chl_M4_lm, partial=FALSE)
# Effect Size for ANOVA (Type I)

Parameter     | Eta2 |       95% CI
-----------------------------------
Site          | 0.13 | [0.00, 1.00]
Genotype      | 0.61 | [0.32, 1.00]
Site:Genotype | 0.10 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_Chl_M4_lm.res<-data.frame(anova(Tol_Chl_M4_lm))
Tol_Chl_M4_lm.res$Predictor<-rownames(Tol_Chl_M4_lm.res)
Tol_Chl_M4_lm.res$EtaSq<-c(eta_squared(Tol_Chl_M4_lm, partial=FALSE)$Eta2, NA)
Tol_Chl_M4_lm.res$Response<-rep("Chlorophyll", nrow(Tol_Chl_M4_lm.res))
Tol_Chl_M4_lm.res$TimeP<-rep("M4", nrow(Tol_Chl_M4_lm.res))
Tol_Chl_M4_lm.res<-Tol_Chl_M4_lm.res %>% dplyr::rename( p.value = "Pr..F.", DF= "Df")

Significant effect of Site and Genotype and Site*Genotype.

Pairwise

#Pairwise comparisons across:

#Genotypes within Sites
emmeans(Tol_Chl_M4_lm, pairwise~Genotype | Site)
$emmeans
Site = KL:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      0.213 0.0198 18    0.171    0.254
 AC12      0.392 0.0198 18    0.351    0.434
 AC8       0.202 0.0198 18    0.160    0.243

Site = SS:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      0.217 0.0198 18    0.176    0.259
 AC12      0.265 0.0198 18    0.224    0.307
 AC8       0.143 0.0198 18    0.101    0.184

Results are given on the log(mu + 1) (not the response) scale. 
Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast    estimate    SE df t.ratio p.value
 AC10 - AC12  -0.1797 0.028 18  -6.428  <.0001
 AC10 - AC8    0.0109 0.028 18   0.391  0.9196
 AC12 - AC8    0.1906 0.028 18   6.819  <.0001

Site = SS:
 contrast    estimate    SE df t.ratio p.value
 AC10 - AC12  -0.0482 0.028 18  -1.724  0.2237
 AC10 - AC8    0.0747 0.028 18   2.672  0.0393
 AC12 - AC8    0.1229 0.028 18   4.396  0.0010

Note: contrasts are still on the log(mu + 1) scale 
P value adjustment: tukey method for comparing a family of 3 estimates 
#Sites within Genotypes
emmeans(Tol_Chl_M4_lm, pairwise~Site | Genotype)
$emmeans
Genotype = AC10:
 Site emmean     SE df lower.CL upper.CL
 KL    0.213 0.0198 18    0.171    0.254
 SS    0.217 0.0198 18    0.176    0.259

Genotype = AC12:
 Site emmean     SE df lower.CL upper.CL
 KL    0.392 0.0198 18    0.351    0.434
 SS    0.265 0.0198 18    0.224    0.307

Genotype = AC8:
 Site emmean     SE df lower.CL upper.CL
 KL    0.202 0.0198 18    0.160    0.243
 SS    0.143 0.0198 18    0.101    0.184

Results are given on the log(mu + 1) (not the response) scale. 
Confidence level used: 0.95 

$contrasts
Genotype = AC10:
 contrast estimate    SE df t.ratio p.value
 KL - SS  -0.00468 0.028 18  -0.167  0.8688

Genotype = AC12:
 contrast estimate    SE df t.ratio p.value
 KL - SS   0.12684 0.028 18   4.537  0.0003

Genotype = AC8:
 contrast estimate    SE df t.ratio p.value
 KL - SS   0.05909 0.028 18   2.114  0.0488

Note: contrasts are still on the log(mu + 1) scale 
##Save p-values

#Genotypes within Sites
Tol_Chl_M4_lm.geno<-data.frame(emmeans(Tol_Chl_M4_lm, pairwise~Genotype | Site)$contrasts)
Tol_Chl_M4_lm.geno<-Tol_Chl_M4_lm.geno %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_Chl_M4_lm.geno$group1<-paste(Tol_Chl_M4_lm.geno$Site, Tol_Chl_M4_lm.geno$group1, sep="_")
Tol_Chl_M4_lm.geno$group2<-paste(Tol_Chl_M4_lm.geno$Site, Tol_Chl_M4_lm.geno$group2, sep="_")

#Sites within Genotypes
Tol_Chl_M4_lm.site<-data.frame(emmeans(Tol_Chl_M4_lm, pairwise~Site | Genotype)$contrasts)
Tol_Chl_M4_lm.site<-Tol_Chl_M4_lm.site %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_Chl_M4_lm.site$group1<-paste(Tol_Chl_M4_lm.site$group1, Tol_Chl_M4_lm.site$Genotype, sep="_")
Tol_Chl_M4_lm.site$group2<-paste(Tol_Chl_M4_lm.site$group2, Tol_Chl_M4_lm.site$Genotype, sep="_")

#Full list of p-values
Tol_Chl_M4_lm.p<-rbind(Tol_Chl_M4_lm.geno[,c(1:2,4:8)], Tol_Chl_M4_lm.site[,c(1:2,4:8)])
Tol_Chl_M4_lm.p<-Tol_Chl_M4_lm.p %>% dplyr::rename( p = p.value)

#Add Significance Levels
Tol_Chl_M4_lm.p$Sig<-ifelse(Tol_Chl_M4_lm.p$p<0.001, "***", ifelse(Tol_Chl_M4_lm.p$p<0.01, "**", ifelse(Tol_Chl_M4_lm.p$p<0.05, "*", NA)))

#Specify Response and Timepoint
Tol_Chl_M4_lm.p$Response<-rep("Chlorophyll", nrow(Tol_Chl_M4_lm.p))
Tol_Chl_M4_lm.p$TimeP<-rep("M4", nrow(Tol_Chl_M4_lm.p))

Plot Retention by Site and Genotype

##Summary statistics by Site and Genotype
Tol_Chl_M4_SG<-summarySE(TolData_M4, measurevar="Chl.prop", groupvars=c("Site.Geno", "Site", "Genotype"), na.rm=TRUE)

##Plot Average Retention across Treatments
Tol_Chl_M4_SG.plot<-ggplot(Tol_Chl_M4_SG, aes(x=Site.Geno, y=Chl.prop, colour=Genotype)) + 
  geom_errorbar(aes(ymin=Chl.prop-se, ymax=Chl.prop+se), width=cap.sz, linewidth=bar.sz)+
  geom_point(size=point.sz)+ 
   ggtitle("Chlorophyll Retention")+
  theme_classic()+
  theme( axis.title.x = element_text(size = axis.title.sz), 
         axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"),
        axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"),
        legend.position="bottom", 
        legend.direction="horizontal",
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="Proportion Retained")+
  ylim(0, 1)+ 
  scale_x_discrete(labels=c("","Klein","","","Something Special",""))+
  scale_color_manual(values = Geno.colors.o)+ 
  stat_pvalue_manual(data=Tol_Chl_M4_lm.p,  y.position=0.55, step.increase=0.20, label="Sig", hide.ns=TRUE); Tol_Chl_M4_SG.plot

Thermal Tolerance Symbionts

Full Set

Run Model

##Check normality
hist(TolData$Sym.prop)

shapiro.test(TolData$Sym.prop)

    Shapiro-Wilk normality test

data:  TolData$Sym.prop
W = 0.92235, p-value = 0.0003707
#Not Normal

##Try log+1 transformation
hist(log(TolData$Sym.prop+1))

shapiro.test(log(TolData$Sym.prop+1))

    Shapiro-Wilk normality test

data:  log(TolData$Sym.prop + 1)
W = 0.92164, p-value = 0.000345
#Not normal 

##Try square transformation
hist((TolData$Sym.prop)^2)

shapiro.test((TolData$Sym.prop)^2)

    Shapiro-Wilk normality test

data:  (TolData$Sym.prop)^2
W = 0.87147, p-value = 3.933e-06
#Not normal 

##Try cubed transformation
hist((TolData$Sym.prop)^3)

shapiro.test((TolData$Sym.prop)^3)

    Shapiro-Wilk normality test

data:  (TolData$Sym.prop)^3
W = 0.80697, p-value = 4.342e-08
#Not normal 


##Model as a function of Site and Genotype and Timepoint
##Model with no transformation and check residuals
Tol_Sym_lm<-lm(Sym.prop~Site+Genotype+TimeP+ Site:Genotype + Site:TimeP + Genotype:TimeP, data=TolData)

Check Residuals

##Check Normality of Residuals
#Distribution 
plot(density(resid(Tol_Sym_lm)))


#Q-Q plot
qqnorm(resid(Tol_Sym_lm)); qqline(resid(Tol_Sym_lm))


##Check Variance of Residuals across Fitted Values
plot(fitted(Tol_Sym_lm), resid(Tol_Sym_lm))

Model Results

#Model Results
summary(Tol_Sym_lm)

Call:
lm(formula = Sym.prop ~ Site + Genotype + TimeP + Site:Genotype + 
    Site:TimeP + Genotype:TimeP, data = TolData)

Residuals:
     Min       1Q   Median       3Q      Max 
-0.37464 -0.08630 -0.00192  0.08972  0.35883 

Coefficients:
                    Estimate Std. Error t value Pr(>|t|)    
(Intercept)         0.544513   0.018576  29.313  < 2e-16 ***
Site.L             -0.001834   0.026197  -0.070 0.944443    
Genotype.L         -0.373179   0.031737 -11.758  < 2e-16 ***
Genotype.Q          0.028101   0.032605   0.862 0.392497    
TimeP.L             0.133503   0.031737   4.206 9.64e-05 ***
TimeP.Q             0.190344   0.032605   5.838 2.94e-07 ***
Site.L:Genotype.L  -0.060389   0.044883  -1.345 0.183999    
Site.L:Genotype.Q   0.074992   0.045930   1.633 0.108240    
Site.L:TimeP.L     -0.159707   0.044883  -3.558 0.000778 ***
Site.L:TimeP.Q     -0.027928   0.045930  -0.608 0.545653    
Genotype.L:TimeP.L  0.085371   0.055316   1.543 0.128489    
Genotype.Q:TimeP.L -0.084924   0.054623  -1.555 0.125749    
Genotype.L:TimeP.Q  0.065986   0.054623   1.208 0.232204    
Genotype.Q:TimeP.Q -0.205029   0.058264  -3.519 0.000878 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.1535 on 55 degrees of freedom
Multiple R-squared:  0.8036,    Adjusted R-squared:  0.7572 
F-statistic: 17.31 on 13 and 55 DF,  p-value: 6.022e-15
anova(Tol_Sym_lm)
Analysis of Variance Table

Response: Sym.prop
               Df Sum Sq Mean Sq F value    Pr(>F)    
Site            1 0.0007 0.00068  0.0289  0.865708    
Genotype        2 3.2796 1.63981 69.5880 8.602e-16 ***
TimeP           2 1.1556 0.57780 24.5197 2.438e-08 ***
Site:Genotype   2 0.1111 0.05557  2.3581  0.104096    
Site:TimeP      2 0.3138 0.15688  6.6576  0.002575 ** 
Genotype:TimeP  4 0.4428 0.11069  4.6974  0.002474 ** 
Residuals      55 1.2961 0.02356                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Effect Size of Predictors
eta_squared(Tol_Sym_lm, partial=FALSE)
# Effect Size for ANOVA (Type I)

Parameter      |     Eta2 |       95% CI
----------------------------------------
Site           | 1.03e-04 | [0.00, 1.00]
Genotype       |     0.50 | [0.33, 1.00]
TimeP          |     0.18 | [0.04, 1.00]
Site:Genotype  |     0.02 | [0.00, 1.00]
Site:TimeP     |     0.05 | [0.00, 1.00]
Genotype:TimeP |     0.07 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_Sym_lm.res<-data.frame(anova(Tol_Sym_lm))
Tol_Sym_lm.res$Predictor<-rownames(Tol_Sym_lm.res)
Tol_Sym_lm.res$EtaSq<-c(eta_squared(Tol_Sym_lm, partial=FALSE)$Eta2, NA)
Tol_Sym_lm.res$Response<-rep("Symbionts", nrow(Tol_Sym_lm.res))
Tol_Sym_lm.res<-Tol_Sym_lm.res %>% dplyr::rename( p.value = "Pr..F.", DF= "Df")

Strong influence of Timepoint, including interactions with main variables of interest, Site and Genotype. Will analyze each Timepoint individually.

Sym Summer 1 Timepoint W2

Run Model

##Check normality
hist(TolData_W2$Sym.prop)

shapiro.test(TolData_W2$Sym.prop)

    Shapiro-Wilk normality test

data:  TolData_W2$Sym.prop
W = 0.93605, p-value = 0.1477
#Normal

##Model as a function of Site and Genotype
Tol_Sym_W2_lm<-lm(Sym.prop~Site+Genotype+Site:Genotype, data=TolData_W2)

Check Residuals

##Check Normality of Residuals
#Distribution 
plot(density(resid(Tol_Sym_W2_lm)))


#Q-Q plot
qqnorm(resid(Tol_Sym_W2_lm)); qqline(resid(Tol_Sym_W2_lm))


##Check Variance of Residuals across Fitted Values
plot(fitted(Tol_Sym_W2_lm), resid(Tol_Sym_W2_lm))

Model Results

Overall

#Model Results
summary(Tol_Sym_W2_lm)

Call:
lm(formula = Sym.prop ~ Site + Genotype + Site:Genotype, data = TolData_W2)

Residuals:
     Min       1Q   Median       3Q      Max 
-0.26060 -0.11145  0.00000  0.08525  0.28580 

Coefficients:
                    Estimate Std. Error t value Pr(>|t|)    
(Intercept)        0.5237625  0.0325072  16.112 9.90e-12 ***
Site.L             0.0939568  0.0459722   2.044   0.0568 .  
Genotype.L        -0.4152131  0.0570402  -7.279 1.29e-06 ***
Genotype.Q        -0.0005205  0.0555584  -0.009   0.9926    
Site.L:Genotype.L -0.2061000  0.0806671  -2.555   0.0205 *  
Site.L:Genotype.Q  0.0462891  0.0785715   0.589   0.5635    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.155 on 17 degrees of freedom
Multiple R-squared:  0.7924,    Adjusted R-squared:  0.7313 
F-statistic: 12.98 on 5 and 17 DF,  p-value: 2.647e-05
anova(Tol_Sym_W2_lm)
Analysis of Variance Table

Response: Sym.prop
              Df  Sum Sq Mean Sq F value    Pr(>F)    
Site           1 0.16148 0.16148  6.7208   0.01897 *  
Genotype       2 1.22843 0.61421 25.5640 7.508e-06 ***
Site:Genotype  2 0.16883 0.08441  3.5133   0.05283 .  
Residuals     17 0.40845 0.02403                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Effect Size of Predictors
eta_squared(Tol_Sym_W2_lm, partial=FALSE)
# Effect Size for ANOVA (Type I)

Parameter     | Eta2 |       95% CI
-----------------------------------
Site          | 0.08 | [0.00, 1.00]
Genotype      | 0.62 | [0.33, 1.00]
Site:Genotype | 0.09 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_Sym_W2_lm.res<-data.frame(anova(Tol_Sym_W2_lm))
Tol_Sym_W2_lm.res$Predictor<-rownames(Tol_Sym_W2_lm.res)
Tol_Sym_W2_lm.res$EtaSq<-c(eta_squared(Tol_Sym_W2_lm, partial=FALSE)$Eta2, NA)
Tol_Sym_W2_lm.res$Response<-rep("Symbionts", nrow(Tol_Sym_W2_lm.res))
Tol_Sym_W2_lm.res$TimeP<-rep("W2", nrow(Tol_Sym_W2_lm.res))
Tol_Sym_W2_lm.res<-Tol_Sym_W2_lm.res %>% dplyr::rename( p.value = "Pr..F.", DF= "Df")

Significant effect of Site and Genotype. Marginal effect (p<0.1) of Site * Genotype. Still checking Site*Genotype for comparability across Timepoints.

Pairwise

#Pairwise comparisons across:

#Genotypes within Sites
emmeans(Tol_Sym_W2_lm, pairwise~Genotype | Site)
$emmeans
Site = KL:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      0.634 0.0775 17   0.4708    0.798
 AC12      0.484 0.0775 17   0.3210    0.648
 AC8       0.253 0.0775 17   0.0897    0.417

Site = SS:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      1.000 0.0775 17   0.8365    1.164
 AC12      0.564 0.0775 17   0.4004    0.727
 AC8       0.207 0.0895 17   0.0179    0.396

Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast    estimate    SE df t.ratio p.value
 AC10 - AC12    0.150 0.110 17   1.367  0.3795
 AC10 - AC8     0.381 0.110 17   3.477  0.0077
 AC12 - AC8     0.231 0.110 17   2.110  0.1174

Site = SS:
 contrast    estimate    SE df t.ratio p.value
 AC10 - AC12    0.436 0.110 17   3.979  0.0026
 AC10 - AC8     0.793 0.118 17   6.701  <.0001
 AC12 - AC8     0.357 0.118 17   3.017  0.0201

P value adjustment: tukey method for comparing a family of 3 estimates 
#Sites within Genotypes
emmeans(Tol_Sym_W2_lm, pairwise~Site | Genotype)
$emmeans
Genotype = AC10:
 Site emmean     SE df lower.CL upper.CL
 KL    0.634 0.0775 17   0.4708    0.798
 SS    1.000 0.0775 17   0.8365    1.164

Genotype = AC12:
 Site emmean     SE df lower.CL upper.CL
 KL    0.484 0.0775 17   0.3210    0.648
 SS    0.564 0.0775 17   0.4004    0.727

Genotype = AC8:
 Site emmean     SE df lower.CL upper.CL
 KL    0.253 0.0775 17   0.0897    0.417
 SS    0.207 0.0895 17   0.0179    0.396

Confidence level used: 0.95 

$contrasts
Genotype = AC10:
 contrast estimate    SE df t.ratio p.value
 KL - SS   -0.3657 0.110 17  -3.337  0.0039

Genotype = AC12:
 contrast estimate    SE df t.ratio p.value
 KL - SS   -0.0794 0.110 17  -0.725  0.4785

Genotype = AC8:
 contrast estimate    SE df t.ratio p.value
 KL - SS    0.0465 0.118 17   0.393  0.6994
##Save p-values

#Genotypes within Sites
Tol_Sym_W2_lm.geno<-data.frame(emmeans(Tol_Sym_W2_lm, pairwise~Genotype | Site)$contrasts)
Tol_Sym_W2_lm.geno<-Tol_Sym_W2_lm.geno %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_Sym_W2_lm.geno$group1<-paste(Tol_Sym_W2_lm.geno$Site, Tol_Sym_W2_lm.geno$group1, sep="_")
Tol_Sym_W2_lm.geno$group2<-paste(Tol_Sym_W2_lm.geno$Site, Tol_Sym_W2_lm.geno$group2, sep="_")

#Sites within Genotypes
Tol_Sym_W2_lm.site<-data.frame(emmeans(Tol_Sym_W2_lm, pairwise~Site | Genotype)$contrasts)
Tol_Sym_W2_lm.site<-Tol_Sym_W2_lm.site %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_Sym_W2_lm.site$group1<-paste(Tol_Sym_W2_lm.site$group1, Tol_Sym_W2_lm.site$Genotype, sep="_")
Tol_Sym_W2_lm.site$group2<-paste(Tol_Sym_W2_lm.site$group2, Tol_Sym_W2_lm.site$Genotype, sep="_")

#Full list of p-values
Tol_Sym_W2_lm.p<-rbind(Tol_Sym_W2_lm.geno[,c(1:2,4:8)], Tol_Sym_W2_lm.site[,c(1:2,4:8)])
Tol_Sym_W2_lm.p<-Tol_Sym_W2_lm.p %>% dplyr::rename( p = p.value)

#Add Significance Levels
Tol_Sym_W2_lm.p$Sig<-ifelse(Tol_Sym_W2_lm.p$p<0.001, "***", ifelse(Tol_Sym_W2_lm.p$p<0.01, "**", ifelse(Tol_Sym_W2_lm.p$p<0.05, "*", NA)))

#Specify Response and Timepoint
Tol_Sym_W2_lm.p$Response<-rep("Symbionts", nrow(Tol_Sym_W2_lm.p))
Tol_Sym_W2_lm.p$TimeP<-rep("W2", nrow(Tol_Sym_W2_lm.p))

Plot Retention by Site and Genotype

##Summary statistics by Site and Genotype
Tol_Sym_W2_SG<-summarySE(TolData_W2, measurevar="Sym.prop", groupvars=c("Site.Geno", "Site", "Genotype"), na.rm=TRUE)

##Plot Average Retention across Treatments
Tol_Sym_W2_SG.plot<-ggplot(Tol_Sym_W2_SG, aes(x=Site.Geno, y=Sym.prop, colour=Genotype)) + 
  geom_errorbar(aes(ymin=Sym.prop-se, ymax=Sym.prop+se), width=cap.sz, linewidth=bar.sz)+
  geom_point(size=point.sz)+ 
   ggtitle("Symbiont Retention")+
  theme_classic()+
  theme( axis.title.x = element_text(size = axis.title.sz), 
         axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"),
        axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"),
        legend.position="bottom", 
        legend.direction="horizontal",
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="Proportion Retained")+
  ylim(0, 1.5)+ 
  scale_x_discrete(labels=c("","Klein","","","Something Special",""))+
  scale_color_manual(values = Geno.colors.o)+ 
  stat_pvalue_manual(data=Tol_Sym_W2_lm.p,  y.position=0.95, step.increase=0.15, label="Sig", hide.ns=TRUE); Tol_Sym_W2_SG.plot

Sym Summer 2 Timepoint M1

Run Model

##Check normality
hist(TolData_M1$Sym.prop)

shapiro.test(TolData_M1$Sym.prop)

    Shapiro-Wilk normality test

data:  TolData_M1$Sym.prop
W = 0.85748, p-value = 0.004618
#Not normal

##Try log+1 transformation
hist(log(TolData_M1$Sym.prop+1))

shapiro.test(log(TolData_M1$Sym.prop+1))

    Shapiro-Wilk normality test

data:  log(TolData_M1$Sym.prop + 1)
W = 0.87335, p-value = 0.009041
#Not normal but improved

##Model as a function of Site and Genotype
##Model with log transformation
Tol_Sym_M1_lm<-lm(log(Sym.prop+1)~Site+Genotype+Site:Genotype, data=TolData_M1)

Check Residuals

##Check Normality of Residuals
#Distribution 
plot(density(resid(Tol_Sym_M1_lm)))


#Q-Q plot
qqnorm(resid(Tol_Sym_M1_lm)); qqline(resid(Tol_Sym_M1_lm))


##Check Variance of Residuals across Fitted Values
plot(fitted(Tol_Sym_M1_lm), resid(Tol_Sym_M1_lm))

Model Results

Overall

#Model Results
summary(Tol_Sym_M1_lm)

Call:
lm(formula = log(Sym.prop + 1) ~ Site + Genotype + Site:Genotype, 
    data = TolData_M1)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.098079 -0.055799 -0.004888  0.043331  0.151113 

Coefficients:
                   Estimate Std. Error t value Pr(>|t|)    
(Intercept)        0.307716   0.016556  18.587 2.95e-12 ***
Site.L             0.027767   0.023413   1.186 0.252954    
Genotype.L        -0.295494   0.027204 -10.862 8.59e-09 ***
Genotype.Q         0.129387   0.030075   4.302 0.000548 ***
Site.L:Genotype.L  0.080682   0.038472   2.097 0.052224 .  
Site.L:Genotype.Q -0.005572   0.042532  -0.131 0.897412    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.07694 on 16 degrees of freedom
Multiple R-squared:  0.8989,    Adjusted R-squared:  0.8673 
F-statistic: 28.46 on 5 and 16 DF,  p-value: 2e-07
anova(Tol_Sym_M1_lm)
Analysis of Variance Table

Response: log(Sym.prop + 1)
              Df  Sum Sq Mean Sq F value    Pr(>F)    
Site           1 0.00823 0.00823  1.3902    0.2556    
Genotype       2 0.80811 0.40406 68.2486 1.468e-08 ***
Site:Genotype  2 0.02614 0.01307  2.2076    0.1423    
Residuals     16 0.09473 0.00592                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Effect Size of Predictors
eta_squared(Tol_Sym_M1_lm, partial=FALSE)
# Effect Size for ANOVA (Type I)

Parameter     |     Eta2 |       95% CI
---------------------------------------
Site          | 8.78e-03 | [0.00, 1.00]
Genotype      |     0.86 | [0.73, 1.00]
Site:Genotype |     0.03 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_Sym_M1_lm.res<-data.frame(anova(Tol_Sym_M1_lm))
Tol_Sym_M1_lm.res$Predictor<-rownames(Tol_Sym_M1_lm.res)
Tol_Sym_M1_lm.res$EtaSq<-c(eta_squared(Tol_Sym_M1_lm, partial=FALSE)$Eta2, NA)
Tol_Sym_M1_lm.res$Response<-rep("Symbionts", nrow(Tol_Sym_M1_lm.res))
Tol_Sym_M1_lm.res$TimeP<-rep("M1", nrow(Tol_Sym_M1_lm.res))
Tol_Sym_M1_lm.res<-Tol_Sym_M1_lm.res %>% dplyr::rename( p.value = "Pr..F.", DF= "Df")

Significant effect of Genotype. Still checking Site*Genotype for comparability across Timepoints.

Pairwise

#Pairwise comparisons across:

#Genotypes within Sites
emmeans(Tol_Sym_M1_lm, pairwise~Genotype | Site)
$emmeans
Site = KL:
 Genotype emmean     SE df lower.CL upper.CL
 AC10     0.5918 0.0385 16   0.5102    0.673
 AC12     0.1792 0.0444 16   0.0850    0.273
 AC8      0.0932 0.0385 16   0.0117    0.175

Site = SS:
 Genotype emmean     SE df lower.CL upper.CL
 AC10     0.5472 0.0385 16   0.4656    0.629
 AC12     0.2249 0.0444 16   0.1307    0.319
 AC8      0.2100 0.0385 16   0.1284    0.292

Results are given on the log(mu + 1) (not the response) scale. 
Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12    0.413 0.0588 16   7.021  <.0001
 AC10 - AC8     0.499 0.0544 16   9.164  <.0001
 AC12 - AC8     0.086 0.0588 16   1.463  0.3339

Site = SS:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12    0.322 0.0588 16   5.483  0.0001
 AC10 - AC8     0.337 0.0544 16   6.198  <.0001
 AC12 - AC8     0.015 0.0588 16   0.255  0.9650

Note: contrasts are still on the log(mu + 1) scale 
P value adjustment: tukey method for comparing a family of 3 estimates 
#Sites within Genotypes
emmeans(Tol_Sym_M1_lm, pairwise~Site | Genotype)
$emmeans
Genotype = AC10:
 Site emmean     SE df lower.CL upper.CL
 KL   0.5918 0.0385 16   0.5102    0.673
 SS   0.5472 0.0385 16   0.4656    0.629

Genotype = AC12:
 Site emmean     SE df lower.CL upper.CL
 KL   0.1792 0.0444 16   0.0850    0.273
 SS   0.2249 0.0444 16   0.1307    0.319

Genotype = AC8:
 Site emmean     SE df lower.CL upper.CL
 KL   0.0932 0.0385 16   0.0117    0.175
 SS   0.2100 0.0385 16   0.1284    0.292

Results are given on the log(mu + 1) (not the response) scale. 
Confidence level used: 0.95 

$contrasts
Genotype = AC10:
 contrast estimate     SE df t.ratio p.value
 KL - SS    0.0446 0.0544 16   0.820  0.4241

Genotype = AC12:
 contrast estimate     SE df t.ratio p.value
 KL - SS   -0.0457 0.0628 16  -0.727  0.4775

Genotype = AC8:
 contrast estimate     SE df t.ratio p.value
 KL - SS   -0.1167 0.0544 16  -2.146  0.0476

Note: contrasts are still on the log(mu + 1) scale 
##Save p-values

#Genotypes within Sites
Tol_Sym_M1_lm.geno<-data.frame(emmeans(Tol_Sym_M1_lm, pairwise~Genotype | Site)$contrasts)
Tol_Sym_M1_lm.geno<-Tol_Sym_M1_lm.geno %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_Sym_M1_lm.geno$group1<-paste(Tol_Sym_M1_lm.geno$Site, Tol_Sym_M1_lm.geno$group1, sep="_")
Tol_Sym_M1_lm.geno$group2<-paste(Tol_Sym_M1_lm.geno$Site, Tol_Sym_M1_lm.geno$group2, sep="_")

#Sites within Genotypes
Tol_Sym_M1_lm.site<-data.frame(emmeans(Tol_Sym_M1_lm, pairwise~Site | Genotype)$contrasts)
Tol_Sym_M1_lm.site<-Tol_Sym_M1_lm.site %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_Sym_M1_lm.site$group1<-paste(Tol_Sym_M1_lm.site$group1, Tol_Sym_M1_lm.site$Genotype, sep="_")
Tol_Sym_M1_lm.site$group2<-paste(Tol_Sym_M1_lm.site$group2, Tol_Sym_M1_lm.site$Genotype, sep="_")

#Full list of p-values
Tol_Sym_M1_lm.p<-rbind(Tol_Sym_M1_lm.geno[,c(1:2,4:8)], Tol_Sym_M1_lm.site[,c(1:2,4:8)])
Tol_Sym_M1_lm.p<-Tol_Sym_M1_lm.p %>% dplyr::rename( p = p.value)

#Add Significance Levels
Tol_Sym_M1_lm.p$Sig<-ifelse(Tol_Sym_M1_lm.p$p<0.001, "***", ifelse(Tol_Sym_M1_lm.p$p<0.01, "**", ifelse(Tol_Sym_M1_lm.p$p<0.05, "*", NA)))

#Specify Response and Timepoint
Tol_Sym_M1_lm.p$Response<-rep("Symbionts", nrow(Tol_Sym_M1_lm.p))
Tol_Sym_M1_lm.p$TimeP<-rep("M1", nrow(Tol_Sym_M1_lm.p))

Plot Retention by Site and Genotype

##Summary statistics by Site and Genotype
Tol_Sym_M1_SG<-summarySE(TolData_M1, measurevar="Sym.prop", groupvars=c("Site.Geno", "Site", "Genotype"), na.rm=TRUE)

##Plot Average Retention across Treatments
Tol_Sym_M1_SG.plot<-ggplot(Tol_Sym_M1_SG, aes(x=Site.Geno, y=Sym.prop, colour=Genotype)) + 
  geom_errorbar(aes(ymin=Sym.prop-se, ymax=Sym.prop+se), width=cap.sz, linewidth=bar.sz)+
  geom_point(size=point.sz)+ 
   ggtitle("Symbiont Retention")+
  theme_classic()+
  theme( axis.title.x = element_text(size = axis.title.sz), 
         axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"),
        axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"),
        legend.position="bottom", 
        legend.direction="horizontal",
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="Proportion Retained")+
 ylim(0, 1.5)+ 
  scale_x_discrete(labels=c("","Klein","","","Something Special",""))+
  scale_color_manual(values = Geno.colors.o)+ 
  stat_pvalue_manual(data=Tol_Sym_M1_lm.p,  y.position=0.95, step.increase=0.15, label="Sig", hide.ns=TRUE); Tol_Sym_M1_SG.plot

Sym Winter Timepoint M4

Run Model

##Check normality
hist(TolData_M4$Sym.prop)

shapiro.test(TolData_M4$Sym.prop)

    Shapiro-Wilk normality test

data:  TolData_M4$Sym.prop
W = 0.88557, p-value = 0.01078
#Not Normal

##Try square transformation
hist((TolData_M4$Sym.prop)^2)

shapiro.test((TolData_M4$Sym.prop)^2)

    Shapiro-Wilk normality test

data:  (TolData_M4$Sym.prop)^2
W = 0.87973, p-value = 0.008208
#Not Normal

##Try cubed transformation
hist((TolData_M4$Sym.prop)^3)

shapiro.test((TolData_M4$Sym.prop)^3)

    Shapiro-Wilk normality test

data:  (TolData_M4$Sym.prop)^3
W = 0.8488, p-value = 0.002077
#Not Normal

##Model as a function of Site and Genotype
##Model with no transformation and check residuals
Tol_Sym_M4_lm<-lm(Sym.prop~Site+Genotype+Site:Genotype, data=TolData_M4)

Check Residuals

##Check Normality of Residuals
#Distribution 
plot(density(resid(Tol_Sym_M4_lm)))


#Q-Q plot
qqnorm(resid(Tol_Sym_M4_lm)); qqline(resid(Tol_Sym_M4_lm))


##Check Variance of Residuals across Fitted Values
plot(fitted(Tol_Sym_M4_lm), resid(Tol_Sym_M4_lm))

Model Results

Overall

#Model Results
summary(Tol_Sym_M4_lm)

Call:
lm(formula = Sym.prop ~ Site + Genotype + Site:Genotype, data = TolData_M4)

Residuals:
     Min       1Q   Median       3Q      Max 
-0.31820 -0.08804  0.00000  0.08618  0.29740 

Coefficients:
                  Estimate Std. Error t value Pr(>|t|)    
(Intercept)        0.71662    0.03157  22.702 1.07e-14 ***
Site.L            -0.12617    0.04464  -2.826   0.0112 *  
Genotype.L        -0.28587    0.05467  -5.229 5.67e-05 ***
Genotype.Q        -0.11565    0.05467  -2.115   0.0486 *  
Site.L:Genotype.L -0.09494    0.07732  -1.228   0.2353    
Site.L:Genotype.Q  0.17275    0.07732   2.234   0.0384 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.1546 on 18 degrees of freedom
Multiple R-squared:  0.7201,    Adjusted R-squared:  0.6423 
F-statistic:  9.26 on 5 and 18 DF,  p-value: 0.0001686
anova(Tol_Sym_M4_lm)
Analysis of Variance Table

Response: Sym.prop
              Df  Sum Sq Mean Sq F value   Pr(>F)    
Site           1 0.19101 0.19101  7.9874 0.011190 *  
Genotype       2 0.76080 0.38040 15.9068 0.000105 ***
Site:Genotype  2 0.15542 0.07771  3.2496 0.062386 .  
Residuals     18 0.43046 0.02391                     
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Effect Size of Predictors
eta_squared(Tol_Sym_M4_lm, partial=FALSE)
# Effect Size for ANOVA (Type I)

Parameter     | Eta2 |       95% CI
-----------------------------------
Site          | 0.12 | [0.00, 1.00]
Genotype      | 0.49 | [0.18, 1.00]
Site:Genotype | 0.10 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_Sym_M4_lm.res<-data.frame(anova(Tol_Sym_M4_lm))
Tol_Sym_M4_lm.res$Predictor<-rownames(Tol_Sym_M4_lm.res)
Tol_Sym_M4_lm.res$EtaSq<-c(eta_squared(Tol_Sym_M4_lm, partial=FALSE)$Eta2, NA)
Tol_Sym_M4_lm.res$Response<-rep("Symbionts", nrow(Tol_Sym_M4_lm.res))
Tol_Sym_M4_lm.res$TimeP<-rep("M4", nrow(Tol_Sym_M4_lm.res))
Tol_Sym_M4_lm.res<-Tol_Sym_M4_lm.res %>% dplyr::rename( p.value = "Pr..F.", DF= "Df")

Significant effect of Site and Genotype. Marginal effect (p<0.1) of Site * Genotype. Still checking Site*Genotype for comparability across Timepoints.

Pairwise

#Pairwise comparisons across:

#Genotypes within Sites
emmeans(Tol_Sym_M4_lm, pairwise~Genotype | Site)
$emmeans
Site = KL:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      0.863 0.0773 18    0.701    1.026
 AC12      1.000 0.0773 18    0.838    1.162
 AC8       0.554 0.0773 18    0.392    0.717

Site = SS:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      0.880 0.0773 18    0.717    1.042
 AC12      0.622 0.0773 18    0.460    0.785
 AC8       0.380 0.0773 18    0.218    0.543

Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast    estimate    SE df t.ratio p.value
 AC10 - AC12   -0.137 0.109 18  -1.249  0.4409
 AC10 - AC8     0.309 0.109 18   2.829  0.0285
 AC12 - AC8     0.446 0.109 18   4.078  0.0019

Site = SS:
 contrast    estimate    SE df t.ratio p.value
 AC10 - AC12    0.258 0.109 18   2.356  0.0734
 AC10 - AC8     0.499 0.109 18   4.565  0.0007
 AC12 - AC8     0.242 0.109 18   2.210  0.0965

P value adjustment: tukey method for comparing a family of 3 estimates 
#Sites within Genotypes
emmeans(Tol_Sym_M4_lm, pairwise~Site | Genotype)
$emmeans
Genotype = AC10:
 Site emmean     SE df lower.CL upper.CL
 KL    0.863 0.0773 18    0.701    1.026
 SS    0.880 0.0773 18    0.717    1.042

Genotype = AC12:
 Site emmean     SE df lower.CL upper.CL
 KL    1.000 0.0773 18    0.838    1.162
 SS    0.622 0.0773 18    0.460    0.785

Genotype = AC8:
 Site emmean     SE df lower.CL upper.CL
 KL    0.554 0.0773 18    0.392    0.717
 SS    0.380 0.0773 18    0.218    0.543

Confidence level used: 0.95 

$contrasts
Genotype = AC10:
 contrast estimate    SE df t.ratio p.value
 KL - SS   -0.0163 0.109 18  -0.149  0.8835

Genotype = AC12:
 contrast estimate    SE df t.ratio p.value
 KL - SS    0.3779 0.109 18   3.456  0.0028

Genotype = AC8:
 contrast estimate    SE df t.ratio p.value
 KL - SS    0.1736 0.109 18   1.588  0.1297
##Save p-values

#Genotypes within Sites
Tol_Sym_M4_lm.geno<-data.frame(emmeans(Tol_Sym_M4_lm, pairwise~Genotype | Site)$contrasts)
Tol_Sym_M4_lm.geno<-Tol_Sym_M4_lm.geno %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_Sym_M4_lm.geno$group1<-paste(Tol_Sym_M4_lm.geno$Site, Tol_Sym_M4_lm.geno$group1, sep="_")
Tol_Sym_M4_lm.geno$group2<-paste(Tol_Sym_M4_lm.geno$Site, Tol_Sym_M4_lm.geno$group2, sep="_")

#Sites within Genotypes
Tol_Sym_M4_lm.site<-data.frame(emmeans(Tol_Sym_M4_lm, pairwise~Site | Genotype)$contrasts)
Tol_Sym_M4_lm.site<-Tol_Sym_M4_lm.site %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_Sym_M4_lm.site$group1<-paste(Tol_Sym_M4_lm.site$group1, Tol_Sym_M4_lm.site$Genotype, sep="_")
Tol_Sym_M4_lm.site$group2<-paste(Tol_Sym_M4_lm.site$group2, Tol_Sym_M4_lm.site$Genotype, sep="_")

#Full list of p-values
Tol_Sym_M4_lm.p<-rbind(Tol_Sym_M4_lm.geno[,c(1:2,4:8)], Tol_Sym_M4_lm.site[,c(1:2,4:8)])
Tol_Sym_M4_lm.p<-Tol_Sym_M4_lm.p %>% dplyr::rename( p = p.value)

#Add Significance Levels
Tol_Sym_M4_lm.p$Sig<-ifelse(Tol_Sym_M4_lm.p$p<0.001, "***", ifelse(Tol_Sym_M4_lm.p$p<0.01, "**", ifelse(Tol_Sym_M4_lm.p$p<0.05, "*", NA)))

#Specify Response and Timepoint
Tol_Sym_M4_lm.p$Response<-rep("Symbionts", nrow(Tol_Sym_M4_lm.p))
Tol_Sym_M4_lm.p$TimeP<-rep("M4", nrow(Tol_Sym_M4_lm.p))

Plot Retention by Site and Genotype

##Summary statistics by Site and Genotype
Tol_Sym_M4_SG<-summarySE(TolData_M4, measurevar="Sym.prop", groupvars=c("Site.Geno", "Site", "Genotype"), na.rm=TRUE)

##Plot Average Retention across Treatments
Tol_Sym_M4_SG.plot<-ggplot(Tol_Sym_M4_SG, aes(x=Site.Geno, y=Sym.prop, colour=Genotype)) + 
  geom_errorbar(aes(ymin=Sym.prop-se, ymax=Sym.prop+se), width=cap.sz, linewidth=bar.sz)+
  geom_point(size=point.sz)+ 
   ggtitle("Symbiont Retention")+
  theme_classic()+
  theme( axis.title.x = element_text(size = axis.title.sz), 
         axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"),
        axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"),
        legend.position="bottom", 
        legend.direction="horizontal",
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="Proportion Retained")+
  ylim(0, 1.5)+ 
  scale_x_discrete(labels=c("","Klein","","","Something Special",""))+
  scale_color_manual(values = Geno.colors.o)+ 
  stat_pvalue_manual(data=Tol_Sym_M4_lm.p,  y.position=1.1, step.increase=0.15, label="Sig", hide.ns=TRUE); Tol_Sym_M4_SG.plot

Thermal Tolerance Color Full Set

Full Set

Run Model

##Check normality
hist(TolData$Score_Full.prop)

shapiro.test(TolData$Score_Full.prop)

    Shapiro-Wilk normality test

data:  TolData$Score_Full.prop
W = 0.90488, p-value = 6.821e-05
#Not Normal

##Try square transformation
hist((TolData$Score_Full.prop)^2)

shapiro.test((TolData$Score_Full.prop)^2)

    Shapiro-Wilk normality test

data:  (TolData$Score_Full.prop)^2
W = 0.9194, p-value = 0.0002754
#Not normal 

##Try cubed transformation
hist((TolData$Score_Full.prop)^3)

shapiro.test((TolData$Score_Full.prop)^3)

    Shapiro-Wilk normality test

data:  (TolData$Score_Full.prop)^3
W = 0.91645, p-value = 0.0002055
#Not normal 


##Model as a function of Site and Genotype and Timepoint
##Model with no transformation and check residuals
Tol_ScoreF_lm<-lm(Score_Full.prop~Site+Genotype+TimeP+ Site:Genotype + Site:TimeP + Genotype:TimeP, data=TolData)

Check Residuals

##Check Normality of Residuals
#Distribution 
plot(density(resid(Tol_ScoreF_lm)))


#Q-Q plot
qqnorm(resid(Tol_ScoreF_lm)); qqline(resid(Tol_ScoreF_lm))


##Check Variance of Residuals across Fitted Values
plot(fitted(Tol_ScoreF_lm), resid(Tol_ScoreF_lm))

Residuals are not great, need to check for other modeling options for Color Full Set.

Model Results

#Model Results
summary(Tol_ScoreF_lm)

Call:
lm(formula = Score_Full.prop ~ Site + Genotype + TimeP + Site:Genotype + 
    Site:TimeP + Genotype:TimeP, data = TolData)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.217253 -0.020809  0.001419  0.037990  0.181147 

Coefficients:
                    Estimate Std. Error t value Pr(>|t|)    
(Intercept)         0.816721   0.010646  76.716  < 2e-16 ***
Site.L              0.068538   0.015014   4.565 2.85e-05 ***
Genotype.L         -0.162107   0.018189  -8.912 2.92e-12 ***
Genotype.Q         -0.000730   0.018686  -0.039  0.96898    
TimeP.L             0.143092   0.018189   7.867 1.44e-10 ***
TimeP.Q            -0.021653   0.018686  -1.159  0.25157    
Site.L:Genotype.L   0.033429   0.025724   1.300  0.19918    
Site.L:Genotype.Q  -0.007619   0.026324  -0.289  0.77333    
Site.L:TimeP.L     -0.039262   0.025724  -1.526  0.13267    
Site.L:TimeP.Q     -0.005353   0.026324  -0.203  0.83961    
Genotype.L:TimeP.L  0.055269   0.031703   1.743  0.08686 .  
Genotype.Q:TimeP.L  0.032487   0.031306   1.038  0.30393    
Genotype.L:TimeP.Q -0.003858   0.031306  -0.123  0.90237    
Genotype.Q:TimeP.Q -0.108144   0.033392  -3.239  0.00204 ** 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.08798 on 55 degrees of freedom
Multiple R-squared:  0.7679,    Adjusted R-squared:  0.7131 
F-statistic:    14 on 13 and 55 DF,  p-value: 4.691e-13
anova(Tol_ScoreF_lm)
Analysis of Variance Table

Response: Score_Full.prop
               Df  Sum Sq  Mean Sq F value    Pr(>F)    
Site            1 0.18599 0.185989 24.0291 8.773e-06 ***
Genotype        2 0.58580 0.292900 37.8415 4.613e-11 ***
TimeP           2 0.48992 0.244959 31.6477 7.135e-10 ***
Site:Genotype   2 0.01497 0.007484  0.9669   0.38664    
Site:TimeP      2 0.02075 0.010376  1.3405   0.27013    
Genotype:TimeP  4 0.11112 0.027780  3.5891   0.01137 *  
Residuals      55 0.42571 0.007740                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Effect Size of Predictors
eta_squared(Tol_ScoreF_lm, partial=FALSE)
# Effect Size for ANOVA (Type I)

Parameter      |     Eta2 |       95% CI
----------------------------------------
Site           |     0.10 | [0.01, 1.00]
Genotype       |     0.32 | [0.15, 1.00]
TimeP          |     0.27 | [0.10, 1.00]
Site:Genotype  | 8.16e-03 | [0.00, 1.00]
Site:TimeP     |     0.01 | [0.00, 1.00]
Genotype:TimeP |     0.06 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_ScoreF_lm.res<-data.frame(anova(Tol_ScoreF_lm))
Tol_ScoreF_lm.res$Predictor<-rownames(Tol_ScoreF_lm.res)
Tol_ScoreF_lm.res$EtaSq<-c(eta_squared(Tol_ScoreF_lm, partial=FALSE)$Eta2, NA)
Tol_ScoreF_lm.res$Response<-rep("Color_FullSet", nrow(Tol_ScoreF_lm.res))
Tol_ScoreF_lm.res<-Tol_ScoreF_lm.res %>% dplyr::rename( p.value = "Pr..F.", DF= "Df")

Strong influence of Timepoint, including interactions with Genotype. Will analyze each Timepoint individually.

Color Score Full Set Summer 1 Timepoint W2

Run Model

##Check normality
hist(TolData_W2$Score_Full.prop)

shapiro.test(TolData_W2$Score_Full.prop)

    Shapiro-Wilk normality test

data:  TolData_W2$Score_Full.prop
W = 0.96098, p-value = 0.4834
#Normal

##Model as a function of Site and Genotype
Tol_ScoreF_W2_lm<-lm(Score_Full.prop~Site+Genotype+Site:Genotype, data=TolData_W2)

Check Residuals

##Check Normality of Residuals
#Distribution 
plot(density(resid(Tol_ScoreF_W2_lm)))


#Q-Q plot
qqnorm(resid(Tol_ScoreF_W2_lm)); qqline(resid(Tol_ScoreF_W2_lm))


##Check Variance of Residuals across Fitted Values
plot(fitted(Tol_ScoreF_W2_lm), resid(Tol_ScoreF_W2_lm))

Model Results

Overall

#Model Results
summary(Tol_ScoreF_W2_lm)

Call:
lm(formula = Score_Full.prop ~ Site + Genotype + Site:Genotype, 
    data = TolData_W2)

Residuals:
     Min       1Q   Median       3Q      Max 
-0.20185 -0.04952 -0.00045  0.04135  0.16725 

Coefficients:
                   Estimate Std. Error t value Pr(>|t|)    
(Intercept)        0.706208   0.023330  30.270 3.15e-16 ***
Site.L             0.093421   0.032994   2.831 0.011517 *  
Genotype.L        -0.203806   0.040938  -4.978 0.000115 ***
Genotype.Q        -0.068453   0.039874  -1.717 0.104193    
Site.L:Genotype.L  0.003375   0.057895   0.058 0.954193    
Site.L:Genotype.Q  0.010407   0.056391   0.185 0.855768    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.1112 on 17 degrees of freedom
Multiple R-squared:  0.6882,    Adjusted R-squared:  0.5964 
F-statistic: 7.503 on 5 and 17 DF,  p-value: 7e-04
anova(Tol_ScoreF_W2_lm)
Analysis of Variance Table

Response: Score_Full.prop
              Df  Sum Sq  Mean Sq F value    Pr(>F)    
Site           1 0.12458 0.124577 10.0661 0.0055647 ** 
Genotype       2 0.33925 0.169625 13.7060 0.0002851 ***
Site:Genotype  2 0.00045 0.000226  0.0183 0.9819098    
Residuals     17 0.21039 0.012376                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Effect Size of Predictors
eta_squared(Tol_ScoreF_W2_lm, partial=FALSE)
# Effect Size for ANOVA (Type I)

Parameter     |     Eta2 |       95% CI
---------------------------------------
Site          |     0.18 | [0.00, 1.00]
Genotype      |     0.50 | [0.17, 1.00]
Site:Genotype | 6.70e-04 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_ScoreF_W2_lm.res<-data.frame(anova(Tol_ScoreF_W2_lm))
Tol_ScoreF_W2_lm.res$Predictor<-rownames(Tol_ScoreF_W2_lm.res)
Tol_ScoreF_W2_lm.res$EtaSq<-c(eta_squared(Tol_ScoreF_W2_lm, partial=FALSE)$Eta2, NA)
Tol_ScoreF_W2_lm.res$Response<-rep("Color_FullSet", nrow(Tol_ScoreF_W2_lm.res))
Tol_ScoreF_W2_lm.res$TimeP<-rep("W2", nrow(Tol_ScoreF_W2_lm.res))
Tol_ScoreF_W2_lm.res<-Tol_ScoreF_W2_lm.res %>% dplyr::rename( p.value = "Pr..F.", DF= "Df")

Significant effect of Site and Genotype. Still checking Site*Genotype for comparability across Timepoints.

Pairwise

#Pairwise comparisons across:

#Genotypes within Sites
emmeans(Tol_ScoreF_W2_lm, pairwise~Genotype | Site)
$emmeans
Site = KL:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      0.755 0.0556 17    0.638    0.872
 AC12      0.702 0.0556 17    0.585    0.819
 AC8       0.463 0.0556 17    0.346    0.581

Site = SS:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      0.890 0.0556 17    0.772    1.007
 AC12      0.822 0.0556 17    0.705    0.940
 AC8       0.605 0.0642 17    0.469    0.740

Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12   0.0529 0.0787 17   0.673  0.7820
 AC10 - AC8    0.2916 0.0787 17   3.707  0.0047
 AC12 - AC8    0.2387 0.0787 17   3.034  0.0195

Site = SS:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12   0.0676 0.0787 17   0.859  0.6723
 AC10 - AC8    0.2848 0.0850 17   3.353  0.0100
 AC12 - AC8    0.2172 0.0850 17   2.557  0.0508

P value adjustment: tukey method for comparing a family of 3 estimates 
#Sites within Genotypes
emmeans(Tol_ScoreF_W2_lm, pairwise~Site | Genotype)
$emmeans
Genotype = AC10:
 Site emmean     SE df lower.CL upper.CL
 KL    0.755 0.0556 17    0.638    0.872
 SS    0.890 0.0556 17    0.772    1.007

Genotype = AC12:
 Site emmean     SE df lower.CL upper.CL
 KL    0.702 0.0556 17    0.585    0.819
 SS    0.822 0.0556 17    0.705    0.940

Genotype = AC8:
 Site emmean     SE df lower.CL upper.CL
 KL    0.463 0.0556 17    0.346    0.581
 SS    0.605 0.0642 17    0.469    0.740

Confidence level used: 0.95 

$contrasts
Genotype = AC10:
 contrast estimate     SE df t.ratio p.value
 KL - SS    -0.135 0.0787 17  -1.713  0.1049

Genotype = AC12:
 contrast estimate     SE df t.ratio p.value
 KL - SS    -0.120 0.0787 17  -1.527  0.1452

Genotype = AC8:
 contrast estimate     SE df t.ratio p.value
 KL - SS    -0.141 0.0850 17  -1.665  0.1142
##Save p-values

#Genotypes within Sites
Tol_ScoreF_W2_lm.geno<-data.frame(emmeans(Tol_ScoreF_W2_lm, pairwise~Genotype | Site)$contrasts)
Tol_ScoreF_W2_lm.geno<-Tol_ScoreF_W2_lm.geno %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_ScoreF_W2_lm.geno$group1<-paste(Tol_ScoreF_W2_lm.geno$Site, Tol_ScoreF_W2_lm.geno$group1, sep="_")
Tol_ScoreF_W2_lm.geno$group2<-paste(Tol_ScoreF_W2_lm.geno$Site, Tol_ScoreF_W2_lm.geno$group2, sep="_")

#Sites within Genotypes
Tol_ScoreF_W2_lm.site<-data.frame(emmeans(Tol_ScoreF_W2_lm, pairwise~Site | Genotype)$contrasts)
Tol_ScoreF_W2_lm.site<-Tol_ScoreF_W2_lm.site %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_ScoreF_W2_lm.site$group1<-paste(Tol_ScoreF_W2_lm.site$group1, Tol_ScoreF_W2_lm.site$Genotype, sep="_")
Tol_ScoreF_W2_lm.site$group2<-paste(Tol_ScoreF_W2_lm.site$group2, Tol_ScoreF_W2_lm.site$Genotype, sep="_")

#Full list of p-values
Tol_ScoreF_W2_lm.p<-rbind(Tol_ScoreF_W2_lm.geno[,c(1:2,4:8)], Tol_ScoreF_W2_lm.site[,c(1:2,4:8)])
Tol_ScoreF_W2_lm.p<-Tol_ScoreF_W2_lm.p %>% dplyr::rename( p = p.value)

#Add Significance Levels
Tol_ScoreF_W2_lm.p$Sig<-ifelse(Tol_ScoreF_W2_lm.p$p<0.001, "***", ifelse(Tol_ScoreF_W2_lm.p$p<0.01, "**", ifelse(Tol_ScoreF_W2_lm.p$p<0.05, "*", NA)))

#Specify Response and Timepoint
Tol_ScoreF_W2_lm.p$Response<-rep("Color_FullSet", nrow(Tol_ScoreF_W2_lm.p))
Tol_ScoreF_W2_lm.p$TimeP<-rep("W2", nrow(Tol_ScoreF_W2_lm.p))

Plot Retention by Site and Genotype

##Summary statistics by Site and Genotype
Tol_ScoreF_W2_SG<-summarySE(TolData_W2, measurevar="Score_Full.prop", groupvars=c("Site.Geno", "Site", "Genotype"), na.rm=TRUE)

##Plot Average Retention across Treatments
Tol_ScoreF_W2_SG.plot<-ggplot(Tol_ScoreF_W2_SG, aes(x=Site.Geno, y=Score_Full.prop, colour=Genotype)) + 
  geom_errorbar(aes(ymin=Score_Full.prop-se, ymax=Score_Full.prop+se), width=cap.sz, linewidth=bar.sz)+
  geom_point(size=point.sz)+ 
   ggtitle("Color Retention Full Set")+
  theme_classic()+
  theme( axis.title.x = element_text(size = axis.title.sz), 
         axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"),
        axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"),
        legend.position="bottom", 
        legend.direction="horizontal",
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="Proportion Retained")+
  ylim(0, 1.5)+ 
  scale_x_discrete(labels=c("","Klein","","","Something Special",""))+
  scale_color_manual(values = Geno.colors.o)+ 
  stat_pvalue_manual(data=Tol_ScoreF_W2_lm.p,  y.position=0.9, step.increase=0.35, label="Sig", hide.ns=TRUE); Tol_ScoreF_W2_SG.plot

Color Score Full Set Summer 2 Timepoint M1

Run Model

##Check normality
hist(TolData_M1$Score_Full.prop)

shapiro.test(TolData_M1$Score_Full.prop)

    Shapiro-Wilk normality test

data:  TolData_M1$Score_Full.prop
W = 0.89042, p-value = 0.01921
#Not normal

##Try square transformation
hist((TolData_M1$Score_Full.prop)^2)

shapiro.test((TolData_M1$Score_Full.prop)^2)

    Shapiro-Wilk normality test

data:  (TolData_M1$Score_Full.prop)^2
W = 0.89427, p-value = 0.02287
#Not normal

##Try cubed transformation
hist((TolData_M1$Score_Full.prop)^3)

shapiro.test((TolData_M1$Score_Full.prop)^3)

    Shapiro-Wilk normality test

data:  (TolData_M1$Score_Full.prop)^3
W = 0.88949, p-value = 0.01842
#Not normal

##Model as a function of Site and Genotype
##Model with no transformation and check residuals
Tol_ScoreF_M1_lm<-lm(Score_Full.prop~Site+Genotype+Site:Genotype, data=TolData_M1)

Check Residuals

##Check Normality of Residuals
#Distribution 
plot(density(resid(Tol_ScoreF_M1_lm)))


#Q-Q plot
qqnorm(resid(Tol_ScoreF_M1_lm)); qqline(resid(Tol_ScoreF_M1_lm))


##Check Variance of Residuals across Fitted Values
plot(fitted(Tol_ScoreF_M1_lm), resid(Tol_ScoreF_M1_lm))

Model Results

Overall

#Model Results
summary(Tol_ScoreF_M1_lm)

Call:
lm(formula = Score_Full.prop ~ Site + Genotype + Site:Genotype, 
    data = TolData_M1)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.205567 -0.027956  0.001925  0.027094  0.192833 

Coefficients:
                  Estimate Std. Error t value Pr(>|t|)    
(Intercept)        0.83440    0.02043  40.846  < 2e-16 ***
Site.L             0.07153    0.02889   2.476 0.024843 *  
Genotype.L        -0.15896    0.03357  -4.736 0.000224 ***
Genotype.Q         0.08757    0.03711   2.360 0.031325 *  
Site.L:Genotype.L  0.07642    0.04747   1.610 0.126961    
Site.L:Genotype.Q  0.01094    0.05248   0.208 0.837562    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.09494 on 16 degrees of freedom
Multiple R-squared:  0.6982,    Adjusted R-squared:  0.6039 
F-statistic: 7.403 on 5 and 16 DF,  p-value: 0.0009114
anova(Tol_ScoreF_M1_lm)
Analysis of Variance Table

Response: Score_Full.prop
              Df   Sum Sq  Mean Sq F value    Pr(>F)    
Site           1 0.057569 0.057569  6.3867 0.0224118 *  
Genotype       2 0.252333 0.126167 13.9969 0.0003061 ***
Site:Genotype  2 0.023755 0.011877  1.3177 0.2952999    
Residuals     16 0.144222 0.009014                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Effect Size of Predictors
eta_squared(Tol_ScoreF_M1_lm, partial=FALSE)
# Effect Size for ANOVA (Type I)

Parameter     | Eta2 |       95% CI
-----------------------------------
Site          | 0.12 | [0.00, 1.00]
Genotype      | 0.53 | [0.19, 1.00]
Site:Genotype | 0.05 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_ScoreF_M1_lm.res<-data.frame(anova(Tol_ScoreF_M1_lm))
Tol_ScoreF_M1_lm.res$Predictor<-rownames(Tol_ScoreF_M1_lm.res)
Tol_ScoreF_M1_lm.res$EtaSq<-c(eta_squared(Tol_ScoreF_M1_lm, partial=FALSE)$Eta2, NA)
Tol_ScoreF_M1_lm.res$Response<-rep("Color_FullSet", nrow(Tol_ScoreF_M1_lm.res))
Tol_ScoreF_M1_lm.res$TimeP<-rep("M1", nrow(Tol_ScoreF_M1_lm.res))
Tol_ScoreF_M1_lm.res<-Tol_ScoreF_M1_lm.res %>% dplyr::rename( p.value = "Pr..F.", DF= "Df")

Significant effect of Site and Genotype. Still checking Site*Genotype for comparability across Timepoints.

Pairwise

#Pairwise comparisons across:

#Genotypes within Sites
emmeans(Tol_ScoreF_M1_lm, pairwise~Genotype | Site)
$emmeans
Site = KL:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      0.967 0.0475 16    0.866    1.068
 AC12      0.719 0.0548 16    0.602    0.835
 AC8       0.666 0.0475 16    0.565    0.766

Site = SS:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      0.998 0.0475 16    0.897    1.099
 AC12      0.807 0.0548 16    0.691    0.923
 AC8       0.850 0.0475 16    0.749    0.950

Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12   0.2484 0.0725 16   3.425  0.0092
 AC10 - AC8    0.3012 0.0671 16   4.487  0.0010
 AC12 - AC8    0.0528 0.0725 16   0.729  0.7504

Site = SS:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12   0.1909 0.0725 16   2.633  0.0452
 AC10 - AC8    0.1484 0.0671 16   2.210  0.0998
 AC12 - AC8   -0.0425 0.0725 16  -0.587  0.8292

P value adjustment: tukey method for comparing a family of 3 estimates 
#Sites within Genotypes
emmeans(Tol_ScoreF_M1_lm, pairwise~Site | Genotype)
$emmeans
Genotype = AC10:
 Site emmean     SE df lower.CL upper.CL
 KL    0.967 0.0475 16    0.866    1.068
 SS    0.998 0.0475 16    0.897    1.099

Genotype = AC12:
 Site emmean     SE df lower.CL upper.CL
 KL    0.719 0.0548 16    0.602    0.835
 SS    0.807 0.0548 16    0.691    0.923

Genotype = AC8:
 Site emmean     SE df lower.CL upper.CL
 KL    0.666 0.0475 16    0.565    0.766
 SS    0.850 0.0475 16    0.749    0.950

Confidence level used: 0.95 

$contrasts
Genotype = AC10:
 contrast estimate     SE df t.ratio p.value
 KL - SS   -0.0311 0.0671 16  -0.463  0.6499

Genotype = AC12:
 contrast estimate     SE df t.ratio p.value
 KL - SS   -0.0885 0.0775 16  -1.142  0.2702

Genotype = AC8:
 contrast estimate     SE df t.ratio p.value
 KL - SS   -0.1839 0.0671 16  -2.739  0.0146
##Save p-values

#Genotypes within Sites
Tol_ScoreF_M1_lm.geno<-data.frame(emmeans(Tol_ScoreF_M1_lm, pairwise~Genotype | Site)$contrasts)
Tol_ScoreF_M1_lm.geno<-Tol_ScoreF_M1_lm.geno %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_ScoreF_M1_lm.geno$group1<-paste(Tol_ScoreF_M1_lm.geno$Site, Tol_ScoreF_M1_lm.geno$group1, sep="_")
Tol_ScoreF_M1_lm.geno$group2<-paste(Tol_ScoreF_M1_lm.geno$Site, Tol_ScoreF_M1_lm.geno$group2, sep="_")

#Sites within Genotypes
Tol_ScoreF_M1_lm.site<-data.frame(emmeans(Tol_ScoreF_M1_lm, pairwise~Site | Genotype)$contrasts)
Tol_ScoreF_M1_lm.site<-Tol_ScoreF_M1_lm.site %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_ScoreF_M1_lm.site$group1<-paste(Tol_ScoreF_M1_lm.site$group1, Tol_ScoreF_M1_lm.site$Genotype, sep="_")
Tol_ScoreF_M1_lm.site$group2<-paste(Tol_ScoreF_M1_lm.site$group2, Tol_ScoreF_M1_lm.site$Genotype, sep="_")

#Full list of p-values
Tol_ScoreF_M1_lm.p<-rbind(Tol_ScoreF_M1_lm.geno[,c(1:2,4:8)], Tol_ScoreF_M1_lm.site[,c(1:2,4:8)])
Tol_ScoreF_M1_lm.p<-Tol_ScoreF_M1_lm.p %>% dplyr::rename( p = p.value)

#Add Significance Levels
Tol_ScoreF_M1_lm.p$Sig<-ifelse(Tol_ScoreF_M1_lm.p$p<0.001, "***", ifelse(Tol_ScoreF_M1_lm.p$p<0.01, "**", ifelse(Tol_ScoreF_M1_lm.p$p<0.05, "*", NA)))

#Specify Response and Timepoint
Tol_ScoreF_M1_lm.p$Response<-rep("Color_FullSet", nrow(Tol_ScoreF_M1_lm.p))
Tol_ScoreF_M1_lm.p$TimeP<-rep("M1", nrow(Tol_ScoreF_M1_lm.p))

Plot Retention by Site and Genotype

##Summary statistics by Site and Genotype
Tol_ScoreF_M1_SG<-summarySE(TolData_M1, measurevar="Score_Full.prop", groupvars=c("Site.Geno", "Site", "Genotype"), na.rm=TRUE)

##Plot Average Retention across Treatments
Tol_ScoreF_M1_SG.plot<-ggplot(Tol_ScoreF_M1_SG, aes(x=Site.Geno, y=Score_Full.prop, colour=Genotype)) + 
  geom_errorbar(aes(ymin=Score_Full.prop-se, ymax=Score_Full.prop+se), width=cap.sz, linewidth=bar.sz)+
  geom_point(size=point.sz)+ 
   ggtitle("Color Retention Full Set")+
  theme_classic()+
  theme( axis.title.x = element_text(size = axis.title.sz), 
         axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"),
        axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"),
        legend.position="bottom", 
        legend.direction="horizontal",
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="Proportion Retained")+
 ylim(0, 1.5)+ 
  scale_x_discrete(labels=c("","Klein","","","Something Special",""))+
  scale_color_manual(values = Geno.colors.o)+ 
  stat_pvalue_manual(data=Tol_ScoreF_M1_lm.p,  y.position=1.1, step.increase=0.2, label="Sig", hide.ns=TRUE); Tol_ScoreF_M1_SG.plot

Color Score Full Set Winter Timepoint M4

Run Model

##Check normality
hist(TolData_M4$Score_Full.prop)

shapiro.test(TolData_M4$Score_Full.prop)

    Shapiro-Wilk normality test

data:  TolData_M4$Score_Full.prop
W = 0.83109, p-value = 0.0009936
#Not Normal

##Try square transformation
hist((TolData_M4$Score_Full.prop)^2)

shapiro.test((TolData_M4$Score_Full.prop)^2)

    Shapiro-Wilk normality test

data:  (TolData_M4$Score_Full.prop)^2
W = 0.8317, p-value = 0.001019
#Not Normal

##Try cubed transformation
hist((TolData_M4$Score_Full.prop)^3)

shapiro.test((TolData_M4$Score_Full.prop)^3)

    Shapiro-Wilk normality test

data:  (TolData_M4$Score_Full.prop)^3
W = 0.83161, p-value = 0.001015
#Not Normal

##Model as a function of Site and Genotype
##Model with no transformation and check residuals
Tol_ScoreF_M4_lm<-lm(Score_Full.prop~Site+Genotype+Site:Genotype, data=TolData_M4)

Check Residuals

##Check Normality of Residuals
#Distribution 
plot(density(resid(Tol_ScoreF_M4_lm)))


#Q-Q plot
qqnorm(resid(Tol_ScoreF_M4_lm)); qqline(resid(Tol_ScoreF_M4_lm))


##Check Variance of Residuals across Fitted Values
plot(fitted(Tol_ScoreF_M4_lm), resid(Tol_ScoreF_M4_lm))

Model Results

Overall

#Model Results
summary(Tol_ScoreF_M4_lm)

Call:
lm(formula = Score_Full.prop ~ Site + Genotype + Site:Genotype, 
    data = TolData_M4)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.137800 -0.019025  0.003675  0.020575  0.099500 

Coefficients:
                  Estimate Std. Error t value Pr(>|t|)    
(Intercept)        0.90906    0.01100  82.614  < 2e-16 ***
Site.L             0.03859    0.01556   2.480   0.0233 *  
Genotype.L        -0.12460    0.01906  -6.538 3.82e-06 ***
Genotype.Q        -0.02191    0.01906  -1.149   0.2654    
Site.L:Genotype.L  0.01901    0.02695   0.705   0.4896    
Site.L:Genotype.Q -0.04168    0.02695  -1.546   0.1394    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.05391 on 18 degrees of freedom
Multiple R-squared:  0.7468,    Adjusted R-squared:  0.6765 
F-statistic: 10.62 on 5 and 18 DF,  p-value: 7.153e-05
anova(Tol_ScoreF_M4_lm)
Analysis of Variance Table

Response: Score_Full.prop
              Df   Sum Sq  Mean Sq F value    Pr(>F)    
Site           1 0.017871 0.017871  6.1496   0.02326 *  
Genotype       2 0.128043 0.064021 22.0308 1.452e-05 ***
Site:Genotype  2 0.008394 0.004197  1.4442   0.26199    
Residuals     18 0.052308 0.002906                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Effect Size of Predictors
eta_squared(Tol_ScoreF_M4_lm, partial=FALSE)
# Effect Size for ANOVA (Type I)

Parameter     | Eta2 |       95% CI
-----------------------------------
Site          | 0.09 | [0.00, 1.00]
Genotype      | 0.62 | [0.34, 1.00]
Site:Genotype | 0.04 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_ScoreF_M4_lm.res<-data.frame(anova(Tol_ScoreF_M4_lm))
Tol_ScoreF_M4_lm.res$Predictor<-rownames(Tol_ScoreF_M4_lm.res)
Tol_ScoreF_M4_lm.res$EtaSq<-c(eta_squared(Tol_ScoreF_M4_lm, partial=FALSE)$Eta2, NA)
Tol_ScoreF_M4_lm.res$Response<-rep("Color_FullSet", nrow(Tol_ScoreF_M4_lm.res))
Tol_ScoreF_M4_lm.res$TimeP<-rep("M4", nrow(Tol_ScoreF_M4_lm.res))
Tol_ScoreF_M4_lm.res<-Tol_ScoreF_M4_lm.res %>% dplyr::rename( p.value = "Pr..F.", DF= "Df")

Significant effect of Site and Genotype. Still checking Site*Genotype for comparability across Timepoints.

Pairwise

#Pairwise comparisons across:

#Genotypes within Sites
emmeans(Tol_ScoreF_M4_lm, pairwise~Genotype | Site)
$emmeans
Site = KL:
 Genotype emmean    SE df lower.CL upper.CL
 AC10      0.982 0.027 18    0.926    1.039
 AC12      0.876 0.027 18    0.819    0.932
 AC8       0.787 0.027 18    0.731    0.844

Site = SS:
 Genotype emmean    SE df lower.CL upper.CL
 AC10      0.994 0.027 18    0.937    1.051
 AC12      0.978 0.027 18    0.922    1.035
 AC8       0.837 0.027 18    0.780    0.893

Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12   0.1069 0.0381 18   2.804  0.0301
 AC10 - AC8    0.1952 0.0381 18   5.122  0.0002
 AC12 - AC8    0.0883 0.0381 18   2.318  0.0788

Site = SS:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12   0.0157 0.0381 18   0.411  0.9115
 AC10 - AC8    0.1572 0.0381 18   4.124  0.0018
 AC12 - AC8    0.1415 0.0381 18   3.713  0.0043

P value adjustment: tukey method for comparing a family of 3 estimates 
#Sites within Genotypes
emmeans(Tol_ScoreF_M4_lm, pairwise~Site | Genotype)
$emmeans
Genotype = AC10:
 Site emmean    SE df lower.CL upper.CL
 KL    0.982 0.027 18    0.926    1.039
 SS    0.994 0.027 18    0.937    1.051

Genotype = AC12:
 Site emmean    SE df lower.CL upper.CL
 KL    0.876 0.027 18    0.819    0.932
 SS    0.978 0.027 18    0.922    1.035

Genotype = AC8:
 Site emmean    SE df lower.CL upper.CL
 KL    0.787 0.027 18    0.731    0.844
 SS    0.837 0.027 18    0.780    0.893

Confidence level used: 0.95 

$contrasts
Genotype = AC10:
 contrast estimate     SE df t.ratio p.value
 KL - SS   -0.0115 0.0381 18  -0.302  0.7663

Genotype = AC12:
 contrast estimate     SE df t.ratio p.value
 KL - SS   -0.1027 0.0381 18  -2.694  0.0148

Genotype = AC8:
 contrast estimate     SE df t.ratio p.value
 KL - SS   -0.0495 0.0381 18  -1.299  0.2103
##Save p-values

#Genotypes within Sites
Tol_ScoreF_M4_lm.geno<-data.frame(emmeans(Tol_ScoreF_M4_lm, pairwise~Genotype | Site)$contrasts)
Tol_ScoreF_M4_lm.geno<-Tol_ScoreF_M4_lm.geno %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_ScoreF_M4_lm.geno$group1<-paste(Tol_ScoreF_M4_lm.geno$Site, Tol_ScoreF_M4_lm.geno$group1, sep="_")
Tol_ScoreF_M4_lm.geno$group2<-paste(Tol_ScoreF_M4_lm.geno$Site, Tol_ScoreF_M4_lm.geno$group2, sep="_")

#Sites within Genotypes
Tol_ScoreF_M4_lm.site<-data.frame(emmeans(Tol_ScoreF_M4_lm, pairwise~Site | Genotype)$contrasts)
Tol_ScoreF_M4_lm.site<-Tol_ScoreF_M4_lm.site %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_ScoreF_M4_lm.site$group1<-paste(Tol_ScoreF_M4_lm.site$group1, Tol_ScoreF_M4_lm.site$Genotype, sep="_")
Tol_ScoreF_M4_lm.site$group2<-paste(Tol_ScoreF_M4_lm.site$group2, Tol_ScoreF_M4_lm.site$Genotype, sep="_")

#Full list of p-values
Tol_ScoreF_M4_lm.p<-rbind(Tol_ScoreF_M4_lm.geno[,c(1:2,4:8)], Tol_ScoreF_M4_lm.site[,c(1:2,4:8)])
Tol_ScoreF_M4_lm.p<-Tol_ScoreF_M4_lm.p %>% dplyr::rename( p = p.value)

#Add Significance Levels
Tol_ScoreF_M4_lm.p$Sig<-ifelse(Tol_ScoreF_M4_lm.p$p<0.001, "***", ifelse(Tol_ScoreF_M4_lm.p$p<0.01, "**", ifelse(Tol_ScoreF_M4_lm.p$p<0.05, "*", NA)))

#Specify Response and Timepoint
Tol_ScoreF_M4_lm.p$Response<-rep("Color_FullSet", nrow(Tol_ScoreF_M4_lm.p))
Tol_ScoreF_M4_lm.p$TimeP<-rep("M4", nrow(Tol_ScoreF_M4_lm.p))

Plot Retention by Site and Genotype

##Summary statistics by Site and Genotype
Tol_ScoreF_M4_SG<-summarySE(TolData_M4, measurevar="Score_Full.prop", groupvars=c("Site.Geno", "Site", "Genotype"), na.rm=TRUE)

##Plot Average Retention across Treatments
Tol_ScoreF_M4_SG.plot<-ggplot(Tol_ScoreF_M4_SG, aes(x=Site.Geno, y=Score_Full.prop, colour=Genotype)) + 
  geom_errorbar(aes(ymin=Score_Full.prop-se, ymax=Score_Full.prop+se), width=cap.sz, linewidth=bar.sz)+
  geom_point(size=point.sz)+ 
   ggtitle("Color Retention Full Set")+
  theme_classic()+
  theme( axis.title.x = element_text(size = axis.title.sz), 
         axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"),
        axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"),
        legend.position="bottom", 
        legend.direction="horizontal",
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="Proportion Retained")+
  ylim(0, 1.5)+ 
  scale_x_discrete(labels=c("","Klein","","","Something Special",""))+
  scale_color_manual(values = Geno.colors.o)+ 
  stat_pvalue_manual(data=Tol_ScoreF_M4_lm.p,  y.position=1.1, step.increase=0.22, label="Sig", hide.ns=TRUE); Tol_ScoreF_M4_SG.plot

Thermal Tolerance Color by Timepoint

Full Set

Run Model

##Check normality
hist(TolData$Score_TP.prop)

shapiro.test(TolData$Score_TP.prop)

    Shapiro-Wilk normality test

data:  TolData$Score_TP.prop
W = 0.9161, p-value = 0.0001986
#Not Normal

##Try square transformation
hist((TolData$Score_TP.prop)^2)

shapiro.test((TolData$Score_TP.prop)^2)

    Shapiro-Wilk normality test

data:  (TolData$Score_TP.prop)^2
W = 0.92506, p-value = 0.0004895
#Not normal 

##Try cubed transformation
hist((TolData$Score_TP.prop)^3)

shapiro.test((TolData$Score_TP.prop)^3)

    Shapiro-Wilk normality test

data:  (TolData$Score_TP.prop)^3
W = 0.92936, p-value = 0.0007674
#Not normal 


##Model as a function of Site and Genotype and Timepoint
##Model with no transformation and check residuals
Tol_ScoreTP_lm<-lm(Score_TP.prop~Site+Genotype+TimeP+ Site:Genotype + Site:TimeP + Genotype:TimeP, data=TolData)

Check Residuals

##Check Normality of Residuals
#Distribution 
plot(density(resid(Tol_ScoreTP_lm)))


#Q-Q plot
qqnorm(resid(Tol_ScoreTP_lm)); qqline(resid(Tol_ScoreTP_lm))


##Check Variance of Residuals across Fitted Values
plot(fitted(Tol_ScoreTP_lm), resid(Tol_ScoreTP_lm))

Residuals are not great, need to check for other modeling options for Color by Timepoint.

Model Results

#Model Results
summary(Tol_ScoreTP_lm)

Call:
lm(formula = Score_TP.prop ~ Site + Genotype + TimeP + Site:Genotype + 
    Site:TimeP + Genotype:TimeP, data = TolData)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.133294 -0.019060  0.000725  0.026225  0.122906 

Coefficients:
                    Estimate Std. Error t value Pr(>|t|)    
(Intercept)         0.883494   0.006319 139.809  < 2e-16 ***
Site.L              0.038546   0.008912   4.325 6.47e-05 ***
Genotype.L         -0.102221   0.010797  -9.468 3.81e-13 ***
Genotype.Q          0.004971   0.011092   0.448 0.655784    
TimeP.L             0.068495   0.010797   6.344 4.45e-08 ***
TimeP.Q             0.021265   0.011092   1.917 0.060411 .  
Site.L:Genotype.L   0.014004   0.015269   0.917 0.363050    
Site.L:Genotype.Q  -0.008574   0.015625  -0.549 0.585424    
Site.L:TimeP.L     -0.036792   0.015269  -2.410 0.019344 *  
Site.L:TimeP.Q     -0.004886   0.015625  -0.313 0.755697    
Genotype.L:TimeP.L  0.029281   0.018818   1.556 0.125448    
Genotype.Q:TimeP.L  0.024642   0.018582   1.326 0.190292    
Genotype.L:TimeP.Q  0.015340   0.018582   0.826 0.412653    
Genotype.Q:TimeP.Q -0.072757   0.019821  -3.671 0.000548 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.05222 on 55 degrees of freedom
Multiple R-squared:  0.763, Adjusted R-squared:  0.7069 
F-statistic: 13.62 on 13 and 55 DF,  p-value: 8.098e-13
anova(Tol_ScoreTP_lm)
Analysis of Variance Table

Response: Score_TP.prop
               Df   Sum Sq  Mean Sq F value    Pr(>F)    
Site            1 0.057199 0.057199 20.9741 2.709e-05 ***
Genotype        2 0.238412 0.119206 43.7110 4.331e-12 ***
TimeP           2 0.117103 0.058552 21.4700 1.284e-07 ***
Site:Genotype   2 0.003221 0.001611  0.5906  0.557481    
Site:TimeP      2 0.017283 0.008642  3.1687  0.049832 *  
Genotype:TimeP  4 0.049580 0.012395  4.5450  0.003041 ** 
Residuals      55 0.149993 0.002727                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Effect Size of Predictors
eta_squared(Tol_ScoreTP_lm, partial=FALSE)
# Effect Size for ANOVA (Type I)

Parameter      |     Eta2 |       95% CI
----------------------------------------
Site           |     0.09 | [0.01, 1.00]
Genotype       |     0.38 | [0.20, 1.00]
TimeP          |     0.19 | [0.04, 1.00]
Site:Genotype  | 5.09e-03 | [0.00, 1.00]
Site:TimeP     |     0.03 | [0.00, 1.00]
Genotype:TimeP |     0.08 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_ScoreTP_lm.res<-data.frame(anova(Tol_ScoreTP_lm))
Tol_ScoreTP_lm.res$Predictor<-rownames(Tol_ScoreTP_lm.res)
Tol_ScoreTP_lm.res$EtaSq<-c(eta_squared(Tol_ScoreTP_lm, partial=FALSE)$Eta2, NA)
Tol_ScoreTP_lm.res$Response<-rep("Color_TP", nrow(Tol_ScoreTP_lm.res))
Tol_ScoreTP_lm.res<-Tol_ScoreTP_lm.res %>% dplyr::rename( p.value = "Pr..F.", DF= "Df")

Strong influence of Timepoint, including interactions with variables of interest, Site and Genotype. Will analyze each Timepoint individually.

Color Score by Timepoint Summer 1 Timepoint W2

Run Model

##Check normality
hist(TolData_W2$Score_TP.prop)

shapiro.test(TolData_W2$Score_TP.prop)

    Shapiro-Wilk normality test

data:  TolData_W2$Score_TP.prop
W = 0.95832, p-value = 0.4302
#Normal

##Model as a function of Site and Genotype
Tol_ScoreTP_W2_lm<-lm(Score_TP.prop~Site+Genotype+Site:Genotype, data=TolData_W2)

Check Residuals

##Check Normality of Residuals
#Distribution 
plot(density(resid(Tol_ScoreTP_W2_lm)))


#Q-Q plot
qqnorm(resid(Tol_ScoreTP_W2_lm)); qqline(resid(Tol_ScoreTP_W2_lm))


##Check Variance of Residuals across Fitted Values
plot(fitted(Tol_ScoreTP_W2_lm), resid(Tol_ScoreTP_W2_lm))

Model Results

Overall

#Model Results
summary(Tol_ScoreTP_W2_lm)

Call:
lm(formula = Score_TP.prop ~ Site + Genotype + Site:Genotype, 
    data = TolData_W2)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.117075 -0.028442 -0.002075  0.023658  0.099425 

Coefficients:
                   Estimate Std. Error t value Pr(>|t|)    
(Intercept)        0.843522   0.013080  64.488  < 2e-16 ***
Site.L             0.062257   0.018498   3.366  0.00367 ** 
Genotype.L        -0.117129   0.022952  -5.103 8.83e-05 ***
Genotype.Q        -0.042426   0.022356  -1.898  0.07485 .  
Site.L:Genotype.L -0.002071   0.032459  -0.064  0.94987    
Site.L:Genotype.Q  0.004044   0.031616   0.128  0.89972    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.06237 on 17 degrees of freedom
Multiple R-squared:  0.7169,    Adjusted R-squared:  0.6336 
F-statistic:  8.61 on 5 and 17 DF,  p-value: 0.0003242
anova(Tol_ScoreTP_W2_lm)
Analysis of Variance Table

Response: Score_TP.prop
              Df   Sum Sq  Mean Sq F value    Pr(>F)    
Site           1 0.054151 0.054151 13.9200 0.0016623 ** 
Genotype       2 0.113242 0.056621 14.5549 0.0002073 ***
Site:Genotype  2 0.000083 0.000041  0.0106 0.9894534    
Residuals     17 0.066133 0.003890                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Effect Size of Predictors
eta_squared(Tol_ScoreTP_W2_lm, partial=FALSE)
# Effect Size for ANOVA (Type I)

Parameter     |     Eta2 |       95% CI
---------------------------------------
Site          |     0.23 | [0.01, 1.00]
Genotype      |     0.48 | [0.15, 1.00]
Site:Genotype | 3.53e-04 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_ScoreTP_W2_lm.res<-data.frame(anova(Tol_ScoreTP_W2_lm))
Tol_ScoreTP_W2_lm.res$Predictor<-rownames(Tol_ScoreTP_W2_lm.res)
Tol_ScoreTP_W2_lm.res$EtaSq<-c(eta_squared(Tol_ScoreTP_W2_lm, partial=FALSE)$Eta2, NA)
Tol_ScoreTP_W2_lm.res$Response<-rep("Color_TP", nrow(Tol_ScoreTP_W2_lm.res))
Tol_ScoreTP_W2_lm.res$TimeP<-rep("W2", nrow(Tol_ScoreTP_W2_lm.res))
Tol_ScoreTP_W2_lm.res<-Tol_ScoreTP_W2_lm.res %>% dplyr::rename( p.value = "Pr..F.", DF= "Df")

Significant effect of Site and Genotype. Still checking Site*Genotype for comparability across Timepoints.

Pairwise

#Pairwise comparisons across:

#Genotypes within Sites
emmeans(Tol_ScoreTP_W2_lm, pairwise~Genotype | Site)
$emmeans
Site = KL:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      0.863 0.0312 17    0.797    0.929
 AC12      0.836 0.0312 17    0.771    0.902
 AC8       0.699 0.0312 17    0.633    0.765

Site = SS:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      0.955 0.0312 17    0.889    1.021
 AC12      0.920 0.0312 17    0.854    0.986
 AC8       0.788 0.0360 17    0.712    0.864

Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12   0.0263 0.0441 17   0.597  0.8236
 AC10 - AC8    0.1636 0.0441 17   3.709  0.0047
 AC12 - AC8    0.1373 0.0441 17   3.112  0.0166

Site = SS:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12   0.0354 0.0441 17   0.803  0.7065
 AC10 - AC8    0.1677 0.0476 17   3.521  0.0070
 AC12 - AC8    0.1323 0.0476 17   2.778  0.0328

P value adjustment: tukey method for comparing a family of 3 estimates 
#Sites within Genotypes
emmeans(Tol_ScoreTP_W2_lm, pairwise~Site | Genotype)
$emmeans
Genotype = AC10:
 Site emmean     SE df lower.CL upper.CL
 KL    0.863 0.0312 17    0.797    0.929
 SS    0.955 0.0312 17    0.889    1.021

Genotype = AC12:
 Site emmean     SE df lower.CL upper.CL
 KL    0.836 0.0312 17    0.771    0.902
 SS    0.920 0.0312 17    0.854    0.986

Genotype = AC8:
 Site emmean     SE df lower.CL upper.CL
 KL    0.699 0.0312 17    0.633    0.765
 SS    0.788 0.0360 17    0.712    0.864

Confidence level used: 0.95 

$contrasts
Genotype = AC10:
 contrast estimate     SE df t.ratio p.value
 KL - SS   -0.0925 0.0441 17  -2.096  0.0513

Genotype = AC12:
 contrast estimate     SE df t.ratio p.value
 KL - SS   -0.0834 0.0441 17  -1.890  0.0759

Genotype = AC8:
 contrast estimate     SE df t.ratio p.value
 KL - SS   -0.0883 0.0476 17  -1.854  0.0812
##Save p-values

#Genotypes within Sites
Tol_ScoreTP_W2_lm.geno<-data.frame(emmeans(Tol_ScoreTP_W2_lm, pairwise~Genotype | Site)$contrasts)
Tol_ScoreTP_W2_lm.geno<-Tol_ScoreTP_W2_lm.geno %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_ScoreTP_W2_lm.geno$group1<-paste(Tol_ScoreTP_W2_lm.geno$Site, Tol_ScoreTP_W2_lm.geno$group1, sep="_")
Tol_ScoreTP_W2_lm.geno$group2<-paste(Tol_ScoreTP_W2_lm.geno$Site, Tol_ScoreTP_W2_lm.geno$group2, sep="_")

#Sites within Genotypes
Tol_ScoreTP_W2_lm.site<-data.frame(emmeans(Tol_ScoreTP_W2_lm, pairwise~Site | Genotype)$contrasts)
Tol_ScoreTP_W2_lm.site<-Tol_ScoreTP_W2_lm.site %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_ScoreTP_W2_lm.site$group1<-paste(Tol_ScoreTP_W2_lm.site$group1, Tol_ScoreTP_W2_lm.site$Genotype, sep="_")
Tol_ScoreTP_W2_lm.site$group2<-paste(Tol_ScoreTP_W2_lm.site$group2, Tol_ScoreTP_W2_lm.site$Genotype, sep="_")

#Full list of p-values
Tol_ScoreTP_W2_lm.p<-rbind(Tol_ScoreTP_W2_lm.geno[,c(1:2,4:8)], Tol_ScoreTP_W2_lm.site[,c(1:2,4:8)])
Tol_ScoreTP_W2_lm.p<-Tol_ScoreTP_W2_lm.p %>% dplyr::rename( p = p.value)

#Add Significance Levels
Tol_ScoreTP_W2_lm.p$Sig<-ifelse(Tol_ScoreTP_W2_lm.p$p<0.001, "***", ifelse(Tol_ScoreTP_W2_lm.p$p<0.01, "**", ifelse(Tol_ScoreTP_W2_lm.p$p<0.05, "*", NA)))

#Specify Response and Timepoint
Tol_ScoreTP_W2_lm.p$Response<-rep("Color_TP", nrow(Tol_ScoreTP_W2_lm.p))
Tol_ScoreTP_W2_lm.p$TimeP<-rep("W2", nrow(Tol_ScoreTP_W2_lm.p))

Plot Retention by Site and Genotype

##Summary statistics by Site and Genotype
Tol_ScoreTP_W2_SG<-summarySE(TolData_W2, measurevar="Score_TP.prop", groupvars=c("Site.Geno", "Site", "Genotype"), na.rm=TRUE)

##Plot Average Retention across Treatments
Tol_ScoreTP_W2_SG.plot<-ggplot(Tol_ScoreTP_W2_SG, aes(x=Site.Geno, y=Score_TP.prop, colour=Genotype)) + 
  geom_errorbar(aes(ymin=Score_TP.prop-se, ymax=Score_TP.prop+se), width=cap.sz, linewidth=bar.sz)+
  geom_point(size=point.sz)+ 
   ggtitle("Color Retention by Timepoint")+
  theme_classic()+
  theme( axis.title.x = element_text(size = axis.title.sz), 
         axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"),
        axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"),
        legend.position="bottom", 
        legend.direction="horizontal",
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="Proportion Retained")+
  ylim(0, 1.5)+ 
  scale_x_discrete(labels=c("","Klein","","","Something Special",""))+
  scale_color_manual(values = Geno.colors.o)+ 
  stat_pvalue_manual(data=Tol_ScoreTP_W2_lm.p,  y.position=1, step.increase=0.45, label="Sig", hide.ns=TRUE); Tol_ScoreTP_W2_SG.plot

Color Score by Timepoint Summer 2 Timepoint M1

Run Model

##Check normality
hist(TolData_M1$Score_TP.prop)

shapiro.test(TolData_M1$Score_TP.prop)

    Shapiro-Wilk normality test

data:  TolData_M1$Score_TP.prop
W = 0.9028, p-value = 0.03383
#Not normal

##Try square transformation
hist((TolData_M1$Score_TP.prop)^2)

shapiro.test((TolData_M1$Score_TP.prop)^2)

    Shapiro-Wilk normality test

data:  (TolData_M1$Score_TP.prop)^2
W = 0.90185, p-value = 0.03238
#Not normal

##Try cubed transformation
hist((TolData_M1$Score_TP.prop)^3)

shapiro.test((TolData_M1$Score_TP.prop)^3)

    Shapiro-Wilk normality test

data:  (TolData_M1$Score_TP.prop)^3
W = 0.89818, p-value = 0.02735
#Not normal

##Model as a function of Site and Genotype
##Model with no transformation and check residuals
Tol_ScoreTP_M1_lm<-lm(Score_TP.prop~Site+Genotype+Site:Genotype, data=TolData_M1)

Check Residuals

##Check Normality of Residuals
#Distribution 
plot(density(resid(Tol_ScoreTP_M1_lm)))


#Q-Q plot
qqnorm(resid(Tol_ScoreTP_M1_lm)); qqline(resid(Tol_ScoreTP_M1_lm))


##Check Variance of Residuals across Fitted Values
plot(fitted(Tol_ScoreTP_M1_lm), resid(Tol_ScoreTP_M1_lm))

Model Results

Overall

#Model Results
summary(Tol_ScoreTP_M1_lm)

Call:
lm(formula = Score_TP.prop ~ Site + Genotype + Site:Genotype, 
    data = TolData_M1)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.125200 -0.020725 -0.001675  0.015662  0.131000 

Coefficients:
                   Estimate Std. Error t value Pr(>|t|)    
(Intercept)        0.866131   0.012681  68.303  < 2e-16 ***
Site.L             0.041582   0.017933   2.319    0.034 *  
Genotype.L        -0.114746   0.020837  -5.507 4.78e-05 ***
Genotype.Q         0.064377   0.023036   2.795    0.013 *  
Site.L:Genotype.L  0.050375   0.029467   1.710    0.107    
Site.L:Genotype.Q  0.004277   0.032577   0.131    0.897    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.05893 on 16 degrees of freedom
Multiple R-squared:  0.7446,    Adjusted R-squared:  0.6647 
F-statistic: 9.327 on 5 and 16 DF,  p-value: 0.0002606
anova(Tol_ScoreTP_M1_lm)
Analysis of Variance Table

Response: Score_TP.prop
              Df   Sum Sq  Mean Sq F value    Pr(>F)    
Site           1 0.019311 0.019311  5.5598   0.03144 *  
Genotype       2 0.132460 0.066230 19.0683 5.822e-05 ***
Site:Genotype  2 0.010210 0.005105  1.4698   0.25940    
Residuals     16 0.055573 0.003473                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Effect Size of Predictors
eta_squared(Tol_ScoreTP_M1_lm, partial=FALSE)
# Effect Size for ANOVA (Type I)

Parameter     | Eta2 |       95% CI
-----------------------------------
Site          | 0.09 | [0.00, 1.00]
Genotype      | 0.61 | [0.30, 1.00]
Site:Genotype | 0.05 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_ScoreTP_M1_lm.res<-data.frame(anova(Tol_ScoreTP_M1_lm))
Tol_ScoreTP_M1_lm.res$Predictor<-rownames(Tol_ScoreTP_M1_lm.res)
Tol_ScoreTP_M1_lm.res$EtaSq<-c(eta_squared(Tol_ScoreTP_M1_lm, partial=FALSE)$Eta2, NA)
Tol_ScoreTP_M1_lm.res$Response<-rep("Color_TP", nrow(Tol_ScoreTP_M1_lm.res))
Tol_ScoreTP_M1_lm.res$TimeP<-rep("M1", nrow(Tol_ScoreTP_M1_lm.res))
Tol_ScoreTP_M1_lm.res<-Tol_ScoreTP_M1_lm.res %>% dplyr::rename( p.value = "Pr..F.", DF= "Df")

Significant effect of Site and Genotype. Still checking Site*Genotype for comparability across Timepoints.

Pairwise

#Pairwise comparisons across:

#Genotypes within Sites
emmeans(Tol_ScoreTP_M1_lm, pairwise~Genotype | Site)
$emmeans
Site = KL:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      0.968 0.0295 16    0.906    1.031
 AC12      0.787 0.0340 16    0.715    0.859
 AC8       0.755 0.0295 16    0.693    0.818

Site = SS:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      0.979 0.0295 16    0.917    1.041
 AC12      0.841 0.0340 16    0.768    0.913
 AC8       0.867 0.0295 16    0.805    0.930

Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12   0.1815 0.0450 16   4.032  0.0026
 AC10 - AC8    0.2127 0.0417 16   5.103  0.0003
 AC12 - AC8    0.0312 0.0450 16   0.693  0.7710

Site = SS:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12   0.1385 0.0450 16   3.077  0.0187
 AC10 - AC8    0.1119 0.0417 16   2.685  0.0408
 AC12 - AC8   -0.0266 0.0450 16  -0.591  0.8269

P value adjustment: tukey method for comparing a family of 3 estimates 
#Sites within Genotypes
emmeans(Tol_ScoreTP_M1_lm, pairwise~Site | Genotype)
$emmeans
Genotype = AC10:
 Site emmean     SE df lower.CL upper.CL
 KL    0.968 0.0295 16    0.906    1.031
 SS    0.979 0.0295 16    0.917    1.041

Genotype = AC12:
 Site emmean     SE df lower.CL upper.CL
 KL    0.787 0.0340 16    0.715    0.859
 SS    0.841 0.0340 16    0.768    0.913

Genotype = AC8:
 Site emmean     SE df lower.CL upper.CL
 KL    0.755 0.0295 16    0.693    0.818
 SS    0.867 0.0295 16    0.805    0.930

Confidence level used: 0.95 

$contrasts
Genotype = AC10:
 contrast estimate     SE df t.ratio p.value
 KL - SS   -0.0109 0.0417 16  -0.262  0.7970

Genotype = AC12:
 contrast estimate     SE df t.ratio p.value
 KL - SS   -0.0539 0.0481 16  -1.119  0.2795

Genotype = AC8:
 contrast estimate     SE df t.ratio p.value
 KL - SS   -0.1116 0.0417 16  -2.679  0.0165
##Save p-values

#Genotypes within Sites
Tol_ScoreTP_M1_lm.geno<-data.frame(emmeans(Tol_ScoreTP_M1_lm, pairwise~Genotype | Site)$contrasts)
Tol_ScoreTP_M1_lm.geno<-Tol_ScoreTP_M1_lm.geno %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_ScoreTP_M1_lm.geno$group1<-paste(Tol_ScoreTP_M1_lm.geno$Site, Tol_ScoreTP_M1_lm.geno$group1, sep="_")
Tol_ScoreTP_M1_lm.geno$group2<-paste(Tol_ScoreTP_M1_lm.geno$Site, Tol_ScoreTP_M1_lm.geno$group2, sep="_")

#Sites within Genotypes
Tol_ScoreTP_M1_lm.site<-data.frame(emmeans(Tol_ScoreTP_M1_lm, pairwise~Site | Genotype)$contrasts)
Tol_ScoreTP_M1_lm.site<-Tol_ScoreTP_M1_lm.site %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_ScoreTP_M1_lm.site$group1<-paste(Tol_ScoreTP_M1_lm.site$group1, Tol_ScoreTP_M1_lm.site$Genotype, sep="_")
Tol_ScoreTP_M1_lm.site$group2<-paste(Tol_ScoreTP_M1_lm.site$group2, Tol_ScoreTP_M1_lm.site$Genotype, sep="_")

#Full list of p-values
Tol_ScoreTP_M1_lm.p<-rbind(Tol_ScoreTP_M1_lm.geno[,c(1:2,4:8)], Tol_ScoreTP_M1_lm.site[,c(1:2,4:8)])
Tol_ScoreTP_M1_lm.p<-Tol_ScoreTP_M1_lm.p %>% dplyr::rename( p = p.value)

#Add Significance Levels
Tol_ScoreTP_M1_lm.p$Sig<-ifelse(Tol_ScoreTP_M1_lm.p$p<0.001, "***", ifelse(Tol_ScoreTP_M1_lm.p$p<0.01, "**", ifelse(Tol_ScoreTP_M1_lm.p$p<0.05, "*", NA)))

#Specify Response and Timepoint
Tol_ScoreTP_M1_lm.p$Response<-rep("Color_TP", nrow(Tol_ScoreTP_M1_lm.p))
Tol_ScoreTP_M1_lm.p$TimeP<-rep("M1", nrow(Tol_ScoreTP_M1_lm.p))

Plot Retention by Site and Genotype

##Summary statistics by Site and Genotype
Tol_ScoreTP_M1_SG<-summarySE(TolData_M1, measurevar="Score_TP.prop", groupvars=c("Site.Geno", "Site", "Genotype"), na.rm=TRUE)

##Plot Average Retention across Treatments
Tol_ScoreTP_M1_SG.plot<-ggplot(Tol_ScoreTP_M1_SG, aes(x=Site.Geno, y=Score_TP.prop, colour=Genotype)) + 
  geom_errorbar(aes(ymin=Score_TP.prop-se, ymax=Score_TP.prop+se), width=cap.sz, linewidth=bar.sz)+
  geom_point(size=point.sz)+ 
   ggtitle("Color Retention by Timepoint")+
  theme_classic()+
  theme( axis.title.x = element_text(size = axis.title.sz), 
         axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"),
        axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"),
        legend.position="bottom", 
        legend.direction="horizontal",
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="Proportion Retained")+
 ylim(0, 1.5)+ 
  scale_x_discrete(labels=c("","Klein","","","Something Special",""))+
  scale_color_manual(values = Geno.colors.o)+ 
  stat_pvalue_manual(data=Tol_ScoreTP_M1_lm.p,  y.position=1.05, step.increase=0.3, label="Sig", hide.ns=TRUE); Tol_ScoreTP_M1_SG.plot

Color Score by Timepoint Winter Timepoint M4

Run Model

##Check normality
hist(TolData_M4$Score_TP.prop)

shapiro.test(TolData_M4$Score_TP.prop)

    Shapiro-Wilk normality test

data:  TolData_M4$Score_TP.prop
W = 0.85397, p-value = 0.002593
#Not Normal

##Try square transformation
hist((TolData_M4$Score_TP.prop)^2)

shapiro.test((TolData_M4$Score_TP.prop)^2)

    Shapiro-Wilk normality test

data:  (TolData_M4$Score_TP.prop)^2
W = 0.85439, p-value = 0.00264
#Not Normal

##Try cubed transformation
hist((TolData_M4$Score_TP.prop)^3)

shapiro.test((TolData_M4$Score_TP.prop)^3)

    Shapiro-Wilk normality test

data:  (TolData_M4$Score_TP.prop)^3
W = 0.85457, p-value = 0.002661
#Not Normal

##Model as a function of Site and Genotype
##Model with no transformation and check residuals
Tol_ScoreTP_M4_lm<-lm(Score_TP.prop~Site+Genotype+Site:Genotype, data=TolData_M4)

Check Residuals

##Check Normality of Residuals
#Distribution 
plot(density(resid(Tol_ScoreTP_M4_lm)))


#Q-Q plot
qqnorm(resid(Tol_ScoreTP_M4_lm)); qqline(resid(Tol_ScoreTP_M4_lm))


##Check Variance of Residuals across Fitted Values
plot(fitted(Tol_ScoreTP_M4_lm), resid(Tol_ScoreTP_M4_lm))

Model Results

Overall

#Model Results
summary(Tol_ScoreTP_M4_lm)

Call:
lm(formula = Score_TP.prop ~ Site + Genotype + Site:Genotype, 
    data = TolData_M4)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.070400 -0.009438  0.004100  0.011281  0.057100 

Coefficients:
                   Estimate Std. Error t value Pr(>|t|)    
(Intercept)        0.940608   0.006243 150.654  < 2e-16 ***
Site.L             0.010536   0.008830   1.193   0.2483    
Genotype.L        -0.075254   0.010814  -6.959 1.68e-06 ***
Genotype.Q        -0.007308   0.010814  -0.676   0.5078    
Site.L:Genotype.L -0.006950   0.015293  -0.454   0.6549    
Site.L:Genotype.Q -0.032086   0.015293  -2.098   0.0503 .  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.03059 on 18 degrees of freedom
Multiple R-squared:  0.7531,    Adjusted R-squared:  0.6846 
F-statistic: 10.98 on 5 and 18 DF,  p-value: 5.763e-05
anova(Tol_ScoreTP_M4_lm)
Analysis of Variance Table

Response: Score_TP.prop
              Df   Sum Sq   Mean Sq F value    Pr(>F)    
Site           1 0.001332 0.0013321  1.4238    0.2483    
Genotype       2 0.045732 0.0228662 24.4414 7.407e-06 ***
Site:Genotype  2 0.004311 0.0021557  2.3042    0.1285    
Residuals     18 0.016840 0.0009355                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Effect Size of Predictors
eta_squared(Tol_ScoreTP_M4_lm, partial=FALSE)
# Effect Size for ANOVA (Type I)

Parameter     | Eta2 |       95% CI
-----------------------------------
Site          | 0.02 | [0.00, 1.00]
Genotype      | 0.67 | [0.41, 1.00]
Site:Genotype | 0.06 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_ScoreTP_M4_lm.res<-data.frame(anova(Tol_ScoreTP_M4_lm))
Tol_ScoreTP_M4_lm.res$Predictor<-rownames(Tol_ScoreTP_M4_lm.res)
Tol_ScoreTP_M4_lm.res$EtaSq<-c(eta_squared(Tol_ScoreTP_M4_lm, partial=FALSE)$Eta2, NA)
Tol_ScoreTP_M4_lm.res$Response<-rep("Color_TP", nrow(Tol_ScoreTP_M4_lm.res))
Tol_ScoreTP_M4_lm.res$TimeP<-rep("M4", nrow(Tol_ScoreTP_M4_lm.res))
Tol_ScoreTP_M4_lm.res<-Tol_ScoreTP_M4_lm.res %>% dplyr::rename( p.value = "Pr..F.", DF= "Df")

Significant effect of Genotype. Still checking Site*Genotype for comparability across Timepoints.

Pairwise

#Pairwise comparisons across:

#Genotypes within Sites
emmeans(Tol_ScoreTP_M4_lm, pairwise~Genotype | Site)
$emmeans
Site = KL:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      0.989 0.0153 18    0.957    1.021
 AC12      0.921 0.0153 18    0.888    0.953
 AC8       0.890 0.0153 18    0.858    0.922

Site = SS:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      0.993 0.0153 18    0.960    1.025
 AC12      0.973 0.0153 18    0.940    1.005
 AC8       0.879 0.0153 18    0.847    0.911

Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12   0.0686 0.0216 18   3.171  0.0139
 AC10 - AC8    0.0995 0.0216 18   4.599  0.0006
 AC12 - AC8    0.0309 0.0216 18   1.429  0.3478

Site = SS:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12   0.0199 0.0216 18   0.922  0.6335
 AC10 - AC8    0.1134 0.0216 18   5.242  0.0002
 AC12 - AC8    0.0934 0.0216 18   4.320  0.0011

P value adjustment: tukey method for comparing a family of 3 estimates 
#Sites within Genotypes
emmeans(Tol_ScoreTP_M4_lm, pairwise~Site | Genotype)
$emmeans
Genotype = AC10:
 Site emmean     SE df lower.CL upper.CL
 KL    0.989 0.0153 18    0.957    1.021
 SS    0.993 0.0153 18    0.960    1.025

Genotype = AC12:
 Site emmean     SE df lower.CL upper.CL
 KL    0.921 0.0153 18    0.888    0.953
 SS    0.973 0.0153 18    0.940    1.005

Genotype = AC8:
 Site emmean     SE df lower.CL upper.CL
 KL    0.890 0.0153 18    0.858    0.922
 SS    0.879 0.0153 18    0.847    0.911

Confidence level used: 0.95 

$contrasts
Genotype = AC10:
 contrast estimate     SE df t.ratio p.value
 KL - SS  -0.00332 0.0216 18  -0.154  0.8795

Genotype = AC12:
 contrast estimate     SE df t.ratio p.value
 KL - SS  -0.05195 0.0216 18  -2.402  0.0273

Genotype = AC8:
 contrast estimate     SE df t.ratio p.value
 KL - SS   0.01057 0.0216 18   0.489  0.6308
##Save p-values

#Genotypes within Sites
Tol_ScoreTP_M4_lm.geno<-data.frame(emmeans(Tol_ScoreTP_M4_lm, pairwise~Genotype | Site)$contrasts)
Tol_ScoreTP_M4_lm.geno<-Tol_ScoreTP_M4_lm.geno %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_ScoreTP_M4_lm.geno$group1<-paste(Tol_ScoreTP_M4_lm.geno$Site, Tol_ScoreTP_M4_lm.geno$group1, sep="_")
Tol_ScoreTP_M4_lm.geno$group2<-paste(Tol_ScoreTP_M4_lm.geno$Site, Tol_ScoreTP_M4_lm.geno$group2, sep="_")

#Sites within Genotypes
Tol_ScoreTP_M4_lm.site<-data.frame(emmeans(Tol_ScoreTP_M4_lm, pairwise~Site | Genotype)$contrasts)
Tol_ScoreTP_M4_lm.site<-Tol_ScoreTP_M4_lm.site %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_ScoreTP_M4_lm.site$group1<-paste(Tol_ScoreTP_M4_lm.site$group1, Tol_ScoreTP_M4_lm.site$Genotype, sep="_")
Tol_ScoreTP_M4_lm.site$group2<-paste(Tol_ScoreTP_M4_lm.site$group2, Tol_ScoreTP_M4_lm.site$Genotype, sep="_")

#Full list of p-values
Tol_ScoreTP_M4_lm.p<-rbind(Tol_ScoreTP_M4_lm.geno[,c(1:2,4:8)], Tol_ScoreTP_M4_lm.site[,c(1:2,4:8)])
Tol_ScoreTP_M4_lm.p<-Tol_ScoreTP_M4_lm.p %>% dplyr::rename( p = p.value)

#Add Significance Levels
Tol_ScoreTP_M4_lm.p$Sig<-ifelse(Tol_ScoreTP_M4_lm.p$p<0.001, "***", ifelse(Tol_ScoreTP_M4_lm.p$p<0.01, "**", ifelse(Tol_ScoreTP_M4_lm.p$p<0.05, "*", NA)))

#Specify Response and Timepoint
Tol_ScoreTP_M4_lm.p$Response<-rep("Color_TP", nrow(Tol_ScoreTP_M4_lm.p))
Tol_ScoreTP_M4_lm.p$TimeP<-rep("M4", nrow(Tol_ScoreTP_M4_lm.p))

Plot Retention by Site and Genotype

##Summary statistics by Site and Genotype
Tol_ScoreTP_M4_SG<-summarySE(TolData_M4, measurevar="Score_TP.prop", groupvars=c("Site.Geno", "Site", "Genotype"), na.rm=TRUE)

##Plot Average Retention across Treatments
Tol_ScoreTP_M4_SG.plot<-ggplot(Tol_ScoreTP_M4_SG, aes(x=Site.Geno, y=Score_TP.prop, colour=Genotype)) + 
  geom_errorbar(aes(ymin=Score_TP.prop-se, ymax=Score_TP.prop+se), width=cap.sz, linewidth=bar.sz)+
  geom_point(size=point.sz)+ 
   ggtitle("Color Retention by Timepoint")+
  theme_classic()+
  theme( axis.title.x = element_text(size = axis.title.sz), 
         axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"),
        axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"),
        legend.position="bottom", 
        legend.direction="horizontal",
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="Proportion Retained")+
  ylim(0, 1.5)+ 
  scale_x_discrete(labels=c("","Klein","","","Something Special",""))+
  scale_color_manual(values = Geno.colors.o)+ 
  stat_pvalue_manual(data=Tol_ScoreTP_M4_lm.p,  y.position=1.1, step.increase=0.4, label="Sig", hide.ns=TRUE); Tol_ScoreTP_M4_SG.plot

Contrasts Across Metrics

Combine Contrast Results

Creating a heatmap to compare the direction and significance of pairwise comparisons across Tolerance metrics. Positive estimates indicate that Group 1 > Group 2. P values of less than 0.05 are considered significant.

##Combine Results
Tol_contrasts<-rbind(Tol_Chl_W2_lm.p, Tol_Chl_M1_lm.p, Tol_Chl_M4_lm.p, 
                     Tol_Sym_W2_lm.p, Tol_Sym_M1_lm.p, Tol_Sym_M4_lm.p, 
                     Tol_ScoreF_W2_lm.p, Tol_ScoreF_M1_lm.p, Tol_ScoreF_M4_lm.p, 
                     Tol_ScoreTP_W2_lm.p, Tol_ScoreTP_M1_lm.p, Tol_ScoreTP_M4_lm.p)

##Create Contrast Column
Tol_contrasts$Contrast<-paste(Tol_contrasts$group1, Tol_contrasts$group2, sep=" v. ")

##Add Set column with Contrast and Timepoint
Tol_contrasts$Set<-paste(Tol_contrasts$TimeP, Tol_contrasts$Contrast, sep=" ")

##Re-order by Seasonal Timepoint
Tol_contrasts$TimeP<-factor(Tol_contrasts$TimeP, levels=c("W2", "M1", "M4"), ordered=TRUE)
Tol_contrasts<- Tol_contrasts %>% arrange(desc(as.numeric(TimeP)))

Tol_contrasts$Set<-factor(Tol_contrasts$Set, levels=c(unique(Tol_contrasts$Set)), ordered=TRUE)

Standardize Response Scale

Convert Estimate to the Response scale (instead of log +1 scale) for models where the response was log transformed

Tol_contrasts$Estimate<-Tol_contrasts$estimate

#Chl M4
Tol_contrasts$Estimate[which(Tol_contrasts$Response=="Chlorophyll" & Tol_contrasts$TimeP=="M4")]<-c(exp(Tol_contrasts$estimate[which(Tol_contrasts$Response=="Chlorophyll" & Tol_contrasts$TimeP=="M4")])-1)

#Sym M1
Tol_contrasts$Estimate[which(Tol_contrasts$Response=="Symbionts" & Tol_contrasts$TimeP=="M1")]<-c(exp(Tol_contrasts$estimate[which(Tol_contrasts$Response=="Symbionts" & Tol_contrasts$TimeP=="M1")])-1)

Contrast Heatmaps

Summer 1 Timepoint W2

Tol_Pairs_W2.plot<-ggplot(data=Tol_contrasts[which(Tol_contrasts$TimeP=="W2"),], aes(x=Response, y=Contrast, fill=Estimate))+
  geom_tile()+
  geom_text(aes(label=Sig), size=sig.sz)+
  scale_fill_gradient2(low="#BA1E02FF", mid="white", high="#3BA0FDFF")+
  theme_bw()+
  ggtitle("Pairwise Contrasts Summer 1")+
  theme(axis.text.x=element_text(size=axis.title.sz, colour="black", angle=45, hjust=1),
        axis.text.y=element_text(size=axis.txt.sz-1, colour="black"),
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="", fill="Estimate");Tol_Pairs_W2.plot

Summer 2 Timepoint M1

Tol_Pairs_M1.plot<-ggplot(data=Tol_contrasts[which(Tol_contrasts$TimeP=="M1"),], aes(x=Response, y=Contrast, fill=Estimate))+
  geom_tile()+
  geom_text(aes(label=Sig), size=sig.sz)+
  scale_fill_gradient2(low="#BA1E02FF", mid="white", high="#3BA0FDFF")+
  theme_bw()+
  ggtitle("Pairwise Contrasts Summer 2")+
  theme(axis.text.x=element_text(size=axis.title.sz, colour="black", angle=45, hjust=1),
        axis.text.y=element_text(size=axis.txt.sz-1, colour="black"),
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="", fill="Estimate");Tol_Pairs_M1.plot

Winter Timepoint M4

Tol_Pairs_M4.plot<-ggplot(data=Tol_contrasts[which(Tol_contrasts$TimeP=="M4"),], aes(x=Response, y=Contrast, fill=Estimate))+
  geom_tile()+
  geom_text(aes(label=Sig), size=sig.sz)+
  scale_fill_gradient2(low="#BA1E02FF", mid="white", high="#3BA0FDFF")+
  theme_bw()+
  ggtitle("Pairwise Contrasts Month 4")+
  theme(axis.text.x=element_text(size=axis.title.sz, colour="black", angle=45, hjust=1),
        axis.text.y=element_text(size=axis.txt.sz-1, colour="black"),
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="", fill="Estimate");Tol_Pairs_M4.plot

All Timepoints

Tol_Pairs.plot<-ggplot(data=Tol_contrasts, aes(x=Response, y=Set, fill=Estimate))+
  geom_tile()+
  geom_text(aes(label=Sig), size=sig.sz)+
  scale_fill_gradient2(low="#BA1E02FF", mid="white", high="#3BA0FDFF")+
  theme_bw()+
  ggtitle("Pairwise Contrasts")+
  theme(axis.text.x=element_text(size=axis.title.sz, colour="black", angle=45, hjust=1),
        axis.text.y=element_text(size=axis.txt.sz-1, colour="black"),
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="", fill="Estimate");Tol_Pairs.plot

Significant Differences

Subsetting Contrasts to only include contrasts with significant differences in at least one of the thermal tolerance metrics (Chlorophyll or Symbiont or Color retention)

##Remove rows with non-significant p-values
Tol_contrasts_sig<-subset(Tol_contrasts, p < 0.05)

##Keep Sets where at least one metric shows a significant difference
Tol_Sets_sig<-data.frame(Set=c(unique(Tol_contrasts_sig$Set)))
Tol_contrasts_sig_Set<-merge(Tol_Sets_sig, Tol_contrasts, all.x=TRUE, all.y=FALSE)
Tol_Pairs_sig.plot<-ggplot(data=Tol_contrasts_sig_Set, aes(x=Response, y=Set, fill=Estimate))+
  geom_tile()+
  geom_text(aes(label=Sig), size=sig.sz)+
  scale_fill_gradient2(low="#BA1E02FF", mid="white", high="#3BA0FDFF")+
  theme_bw()+
  ggtitle("Significant Pairwise Contrasts")+
  theme(axis.text.x=element_text(size=axis.title.sz, colour="black", angle=45, hjust=1),
        axis.text.y=element_text(size=axis.txt.sz-1, colour="black"),
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="", fill="Estimate");Tol_Pairs_sig.plot

Proportion of Agreement

Assessing the proportion of agreement between methods as the pairwise comparisons where two methods both find a significant difference out of the total pairwise comparisons. Calculating the proportion of agreement between Chlorophyll and Color Full Set, Chlorophyll and Color Timepoint, Symbionts and Color Full Set, Symbionts and Color Timepoint, and Chlorophyll and Symbionts. Comparing the proportion of agreement between methods of quantifying thermal tolerance.

names(Tol_contrasts)
 [1] "group1"   "group2"   "estimate" "SE"       "df"       "t.ratio"  "p"        "Sig"      "Response"
[10] "TimeP"    "Contrast" "Set"      "Estimate"
##Change long to short format
Tol_contrasts.agree<-Tol_contrasts %>% pivot_wider(names_from="Response", values_from=c("p", "Estimate"), id_cols=c("TimeP", "Contrast", "Set"))

##Convert p values to binary
#0: No significant difference (p>0.05) detected in that pairwise contrast
#1: Significant difference (p<0.05) detected in that pairwise contrast
Tol_contrasts.agree[,c(4:7)]<-ifelse(Tol_contrasts.agree[,c(4:7)]<0.05, 1, 0)

##Convert estimates to Greater or Less
#Greater: Positive estimates indicate A>B in the Contrast
#Less: Negative estimates indicate A<B in the Contrast
Tol_contrasts.agree[,c(8:11)]<-ifelse(Tol_contrasts.agree[,c(8:11)]<0, "Less", "Greater")

##Identify agreement
#1: Both metrics identified a significant difference in that pairwise contrast OR Neither metric identified a significant difference
#0: One metrics identified a significant difference in that pairwise contrast
#For each matching case (1), confirm matching Estimates
Tol_contrasts.agree$Chl.Sym<-ifelse(Tol_contrasts.agree$p_Chlorophyll==1 &
Tol_contrasts.agree$p_Chlorophyll==Tol_contrasts.agree$p_Symbionts &
Tol_contrasts.agree$Estimate_Chlorophyll==Tol_contrasts.agree$Estimate_Symbionts, 1, 
ifelse(Tol_contrasts.agree$p_Chlorophyll==0 & 
         Tol_contrasts.agree$p_Chlorophyll==Tol_contrasts.agree$p_Symbionts, 1, 0))

Tol_contrasts.agree$Chl.ColF<-ifelse(Tol_contrasts.agree$p_Chlorophyll==1 &                                     Tol_contrasts.agree$p_Chlorophyll==Tol_contrasts.agree$p_Color_FullSet &
Tol_contrasts.agree$Estimate_Chlorophyll==Tol_contrasts.agree$Estimate_Color_FullSet, 1, 
ifelse(Tol_contrasts.agree$p_Chlorophyll==0 &
         Tol_contrasts.agree$p_Chlorophyll==Tol_contrasts.agree$p_Color_FullSet, 1, 0))

Tol_contrasts.agree$Chl.ColTP<-ifelse(Tol_contrasts.agree$p_Chlorophyll==1 & 
Tol_contrasts.agree$p_Chlorophyll==Tol_contrasts.agree$p_Color_TP &                          Tol_contrasts.agree$Estimate_Chlorophyll==Tol_contrasts.agree$Estimate_Color_TP, 1, 
ifelse(Tol_contrasts.agree$p_Chlorophyll==0 &
         Tol_contrasts.agree$p_Chlorophyll==Tol_contrasts.agree$p_Color_TP, 1, 0))

Tol_contrasts.agree$Sym.ColF<-ifelse(Tol_contrasts.agree$p_Symbionts==1 &
Tol_contrasts.agree$p_Symbionts==Tol_contrasts.agree$p_Color_FullSet & Tol_contrasts.agree$Estimate_Symbionts==Tol_contrasts.agree$Estimate_Color_FullSet, 1,
ifelse(Tol_contrasts.agree$p_Symbionts==0 &
         Tol_contrasts.agree$p_Symbionts==Tol_contrasts.agree$p_Color_FullSet, 1, 0))

Tol_contrasts.agree$Sym.ColTP<-ifelse(Tol_contrasts.agree$p_Symbionts==1 &
Tol_contrasts.agree$p_Symbionts==Tol_contrasts.agree$p_Color_TP & Tol_contrasts.agree$Estimate_Symbionts==Tol_contrasts.agree$Estimate_Color_TP, 1,
ifelse(Tol_contrasts.agree$p_Symbionts==0 &
         Tol_contrasts.agree$p_Symbionts==Tol_contrasts.agree$p_Color_TP, 1, 0))

Tol_contrasts.agree$ColF.ColTP<-ifelse(Tol_contrasts.agree$p_Color_FullSet==1 &
Tol_contrasts.agree$p_Color_FullSet==Tol_contrasts.agree$p_Color_TP & Tol_contrasts.agree$Estimate_Color_FullSet==Tol_contrasts.agree$Estimate_Color_TP, 1, 
ifelse(Tol_contrasts.agree$p_Color_FullSet==0 &
         Tol_contrasts.agree$p_Color_FullSet==Tol_contrasts.agree$p_Color_TP, 1, 0))

##Convert to long to calculate instances of agreement
Tol_contrasts.agree.long<-Tol_contrasts.agree %>% pivot_longer(cols=c("Chl.Sym", "Chl.ColF", "Chl.ColTP", "Sym.ColF", "Sym.ColTP", "ColF.ColTP"), names_to="Compare", values_to="Agree")

##Sum Cases of Agreement
Tol_contrasts.agree.sum<-aggregate(Tol_contrasts.agree.long$Agree, list(Tol_contrasts.agree.long$Compare), sum)
names(Tol_contrasts.agree.sum)<-c("Compare", "Agree")

##Total Pairwise Comparisons
Tol_contrasts.agree.sum$Total<-aggregate(Tol_contrasts.agree.long$Agree, list(Tol_contrasts.agree.long$Compare), function(x) length(x))[,2]

Compare Proportion Agreement

prop.test(Tol_contrasts.agree.sum$Agree, Tol_contrasts.agree.sum$Total)

    6-sample test for equality of proportions without continuity correction

data:  Tol_contrasts.agree.sum$Agree out of Tol_contrasts.agree.sum$Total
X-squared = 6.0509, df = 5, p-value = 0.3013
alternative hypothesis: two.sided
sample estimates:
   prop 1    prop 2    prop 3    prop 4    prop 5    prop 6 
0.7777778 0.7777778 0.7037037 0.9259259 0.6666667 0.7407407 

No significant difference in the proportion of agreement in detecting pairwise differences in thermal tolerance across comparisons of traditional bleaching or color score methods (Pearson’s chi-squared test p-value = 0.3013)

Compare Agreement across Seasons

##Sum Cases of Agreement by Comparison and Timepoint
Tol_contrasts.agree.sum.tp<-aggregate(Tol_contrasts.agree.long$Agree, list(Tol_contrasts.agree.long$TimeP, Tol_contrasts.agree.long$Compare), sum)
names(Tol_contrasts.agree.sum.tp)<-c("TimeP", "Compare", "Agree")

##Total Pairwise Comparisons
Tol_contrasts.agree.sum.tp$Total<-aggregate(Tol_contrasts.agree.long$Agree, list(Tol_contrasts.agree.long$TimeP, Tol_contrasts.agree.long$Compare), function(x) length(x))[,3]

Chl vs Sym

##Subset by Comparison
Tol_contrasts.agree.Chl.Sym<-subset(Tol_contrasts.agree.sum.tp, Compare=="Chl.Sym")

##Compare Proportions between Timepoints
prop.test(Tol_contrasts.agree.Chl.Sym$Agree, Tol_contrasts.agree.Chl.Sym$Total)
Warning: Chi-squared approximation may be incorrect

    3-sample test for equality of proportions without continuity correction

data:  Tol_contrasts.agree.Chl.Sym$Agree out of Tol_contrasts.agree.Chl.Sym$Total
X-squared = 5.6842, df = 2, p-value = 0.0583
alternative hypothesis: two.sided
sample estimates:
   prop 1    prop 2    prop 3 
0.5555556 1.0000000 0.5555556 

Chl vs Color Full

##Subset by Comparison
Tol_contrasts.agree.Chl.ColF<-subset(Tol_contrasts.agree.sum.tp, Compare=="Chl.ColF")

##Compare Proportions between Timepoints
prop.test(Tol_contrasts.agree.Chl.ColF$Agree, Tol_contrasts.agree.Chl.ColF$Total)
Warning: Chi-squared approximation may be incorrect

    3-sample test for equality of proportions without continuity correction

data:  Tol_contrasts.agree.Chl.ColF$Agree out of Tol_contrasts.agree.Chl.ColF$Total
X-squared = 9, df = 2, p-value = 0.01111
alternative hypothesis: two.sided
sample estimates:
   prop 1    prop 2    prop 3 
1.0000000 0.8888889 0.4444444 

Chl vs Color Timepoint

##Subset by Comparison
Tol_contrasts.agree.Chl.ColTP<-subset(Tol_contrasts.agree.sum.tp, Compare=="Chl.ColTP")

##Compare Proportions between Timepoints
prop.test(Tol_contrasts.agree.Chl.ColTP$Agree, Tol_contrasts.agree.Chl.ColTP$Total)
Warning: Chi-squared approximation may be incorrect

    3-sample test for equality of proportions without continuity correction

data:  Tol_contrasts.agree.Chl.ColTP$Agree out of Tol_contrasts.agree.Chl.ColTP$Total
X-squared = 9, df = 2, p-value = 0.01111
alternative hypothesis: two.sided
sample estimates:
   prop 1    prop 2    prop 3 
0.8888889 1.0000000 0.4444444 

Sym vs Color Full

##Subset by Comparison
Tol_contrasts.agree.Sym.ColF<-subset(Tol_contrasts.agree.sum.tp, Compare=="Sym.ColF")

##Compare Proportions between Timepoints
prop.test(Tol_contrasts.agree.Sym.ColF$Agree, Tol_contrasts.agree.Sym.ColF$Total)
Warning: Chi-squared approximation may be incorrect

    3-sample test for equality of proportions without continuity correction

data:  Tol_contrasts.agree.Sym.ColF$Agree out of Tol_contrasts.agree.Sym.ColF$Total
X-squared = 3, df = 2, p-value = 0.2231
alternative hypothesis: two.sided
sample estimates:
   prop 1    prop 2    prop 3 
0.5555556 0.8888889 0.5555556 

Sym vs Color Timepoint

##Subset by Comparison
Tol_contrasts.agree.Sym.ColTP<-subset(Tol_contrasts.agree.sum.tp, Compare=="Sym.ColTP")

##Compare Proportions between Timepoints
prop.test(Tol_contrasts.agree.Sym.ColTP$Agree, Tol_contrasts.agree.Sym.ColTP$Total)
Warning: Chi-squared approximation may be incorrect

    3-sample test for equality of proportions without continuity correction

data:  Tol_contrasts.agree.Sym.ColTP$Agree out of Tol_contrasts.agree.Sym.ColTP$Total
X-squared = 5.0143, df = 2, p-value = 0.0815
alternative hypothesis: two.sided
sample estimates:
   prop 1    prop 2    prop 3 
0.6666667 1.0000000 0.5555556 

Color Full vs Color Timepoint

##Subset by Comparison
Tol_contrasts.agree.ColF.ColTP<-subset(Tol_contrasts.agree.sum.tp, Compare=="ColF.ColTP")

##Compare Proportions between Timepoints
prop.test(Tol_contrasts.agree.ColF.ColTP$Agree, Tol_contrasts.agree.ColF.ColTP$Total)
Warning: Chi-squared approximation may be incorrect

    3-sample test for equality of proportions without continuity correction

data:  Tol_contrasts.agree.ColF.ColTP$Agree out of Tol_contrasts.agree.ColF.ColTP$Total
X-squared = 1.08, df = 2, p-value = 0.5827
alternative hypothesis: two.sided
sample estimates:
   prop 1    prop 2    prop 3 
0.8888889 0.8888889 1.0000000 

Figures

Figure S2 Tolerance Across Metrics

Update for Panel

Tol_Chl_W2_SG.plot.fig<-ggplot(Tol_Chl_W2_SG, aes(x=Site.Geno, y=Chl.prop, colour=Genotype)) + 
  geom_errorbar(aes(ymin=Chl.prop-se, ymax=Chl.prop+se), width=cap.sz, linewidth=bar.sz)+
  geom_point(size=point.sz)+ 
  ggtitle("Summer 1")+
  theme_classic()+
  theme( axis.title.x = element_text(size = axis.title.sz), 
         axis.title.y = element_text(size = axis.title.sz), 
         axis.text.x=element_text(size=axis.txt.sz, colour="black"),
         axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
         legend.text=element_text(size=leg.txt.sz),
         legend.title=element_text(size=leg.title.sz), 
         legend.box.background = element_rect(color = "black"),
         legend.position="top", 
         legend.direction="horizontal",
         plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="Proportion Chlorophyll Retained")+
  ylim(0, 1)+ 
  scale_x_discrete(labels=c("","Klein","","","Something Special",""))+
  scale_color_manual(values = Geno.colors.o)+ 
  stat_pvalue_manual(data=Tol_Chl_W2_lm.p,  y.position=0.4, step.increase=0.25, label="Sig", hide.ns=TRUE)


Tol_Chl_M1_SG.plot.fig<-ggplot(Tol_Chl_M1_SG, aes(x=Site.Geno, y=Chl.prop, colour=Genotype)) + 
  geom_errorbar(aes(ymin=Chl.prop-se, ymax=Chl.prop+se), width=cap.sz, linewidth=bar.sz)+
  geom_point(size=point.sz)+ 
  ggtitle("Summer 2")+
  theme_classic()+
  theme( axis.title.x = element_text(size = axis.title.sz), 
         axis.title.y = element_text(size = axis.title.sz), 
         axis.text.x=element_text(size=axis.txt.sz, colour="black"),
         axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
         legend.text=element_text(size=leg.txt.sz),
         legend.title=element_text(size=leg.title.sz), 
         legend.box.background = element_rect(color = "black"),
         legend.position="top", 
         legend.direction="horizontal",
         plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="")+
  ylim(0, 1)+ 
  scale_x_discrete(labels=c("","Klein","","","Something Special",""))+
  scale_color_manual(values = Geno.colors.o)+ 
  stat_pvalue_manual(data=Tol_Chl_M1_lm.p,  y.position=0.4, step.increase=0.25, label="Sig", hide.ns=TRUE)


Tol_Chl_M4_SG.plot.fig<-ggplot(Tol_Chl_M4_SG, aes(x=Site.Geno, y=Chl.prop, colour=Genotype)) + 
  geom_errorbar(aes(ymin=Chl.prop-se, ymax=Chl.prop+se), width=cap.sz, linewidth=bar.sz)+
  geom_point(size=point.sz)+ 
  ggtitle("Winter")+
  theme_classic()+
  theme( axis.title.x = element_text(size = axis.title.sz), 
         axis.title.y = element_text(size = axis.title.sz), 
         axis.text.x=element_text(size=axis.txt.sz, colour="black"),
         axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
         legend.text=element_text(size=leg.txt.sz),
         legend.title=element_text(size=leg.title.sz), 
         legend.box.background = element_rect(color = "black"),
         legend.position="top", 
         legend.direction="horizontal",
         plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="")+
  ylim(0, 1)+ 
  scale_x_discrete(labels=c("","Klein","","","Something Special",""))+
  scale_color_manual(values = Geno.colors.o)+ 
  stat_pvalue_manual(data=Tol_Chl_M4_lm.p,  y.position=0.55, step.increase=0.20, label="Sig", hide.ns=TRUE)


Tol_Sym_W2_SG.plot.fig<-ggplot(Tol_Sym_W2_SG, aes(x=Site.Geno, y=Sym.prop, colour=Genotype)) + 
  geom_errorbar(aes(ymin=Sym.prop-se, ymax=Sym.prop+se), width=cap.sz, linewidth=bar.sz)+
  geom_point(size=point.sz)+ 
  theme_classic()+
  theme( axis.title.x = element_text(size = axis.title.sz), 
         axis.title.y = element_text(size = axis.title.sz), 
         axis.text.x=element_text(size=axis.txt.sz, colour="black"),
         axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
         legend.position="none")+
  labs(x="Site and Genotype", y="Proportion Symbionts Retained")+
  ylim(0, 1.5)+ 
  scale_x_discrete(labels=c("","Klein","","","Something Special",""))+
  scale_color_manual(values = Geno.colors.o)+ 
  stat_pvalue_manual(data=Tol_Sym_W2_lm.p,  y.position=0.95, step.increase=0.15, label="Sig", hide.ns=TRUE)


Tol_Sym_M1_SG.plot.fig<-ggplot(Tol_Sym_M1_SG, aes(x=Site.Geno, y=Sym.prop, colour=Genotype)) + 
  geom_errorbar(aes(ymin=Sym.prop-se, ymax=Sym.prop+se), width=cap.sz, linewidth=bar.sz)+
  geom_point(size=point.sz)+ 
  theme_classic()+
  theme( axis.title.x = element_text(size = axis.title.sz), 
         axis.title.y = element_text(size = axis.title.sz), 
         axis.text.x=element_text(size=axis.txt.sz, colour="black"),
         axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
         legend.position="none")+
  labs(x="Site and Genotype", y="")+
  ylim(0, 1.5)+ 
  scale_x_discrete(labels=c("","Klein","","","Something Special",""))+
  scale_color_manual(values = Geno.colors.o)+ 
  stat_pvalue_manual(data=Tol_Sym_M1_lm.p,  y.position=0.95, step.increase=0.15, label="Sig", hide.ns=TRUE)


Tol_Sym_M4_SG.plot.fig<-ggplot(Tol_Sym_M4_SG, aes(x=Site.Geno, y=Sym.prop, colour=Genotype)) + 
  geom_errorbar(aes(ymin=Sym.prop-se, ymax=Sym.prop+se), width=cap.sz, linewidth=bar.sz)+
  geom_point(size=point.sz)+ 
  theme_classic()+
  theme( axis.title.x = element_text(size = axis.title.sz), 
         axis.title.y = element_text(size = axis.title.sz), 
         axis.text.x=element_text(size=axis.txt.sz, colour="black"),
         axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
         legend.position="none")+
  labs(x="Site and Genotype", y="")+
  ylim(0, 1.5)+ 
  scale_x_discrete(labels=c("","Klein","","","Something Special",""))+
  scale_color_manual(values = Geno.colors.o)+ 
  stat_pvalue_manual(data=Tol_Sym_M4_lm.p,  y.position=1.1, step.increase=0.15, label="Sig", hide.ns=TRUE)


Tol_ScoreF_W2_SG.plot.fig<-ggplot(Tol_ScoreF_W2_SG, aes(x=Site.Geno, y=Score_Full.prop, colour=Genotype)) + 
  geom_errorbar(aes(ymin=Score_Full.prop-se, ymax=Score_Full.prop+se), width=cap.sz, linewidth=bar.sz)+
  geom_point(size=point.sz)+ 
  theme_classic()+
  theme( axis.title.x = element_text(size = axis.title.sz), 
         axis.title.y = element_text(size = axis.title.sz), 
         axis.text.x=element_text(size=axis.txt.sz, colour="black"),
         axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
         legend.position="none")+
  labs(x="", y="Proportion Color Retained (Full)")+
  ylim(0.25, 1.5)+ 
  scale_x_discrete(labels=c("","Klein","","","Something Special",""))+
  scale_color_manual(values = Geno.colors.o)+ 
  stat_pvalue_manual(data=Tol_ScoreF_W2_lm.p,  y.position=0.9, step.increase=0.35, label="Sig", hide.ns=TRUE)


Tol_ScoreF_M1_SG.plot.fig<-ggplot(Tol_ScoreF_M1_SG, aes(x=Site.Geno, y=Score_Full.prop, colour=Genotype)) + 
  geom_errorbar(aes(ymin=Score_Full.prop-se, ymax=Score_Full.prop+se), width=cap.sz, linewidth=bar.sz)+
  geom_point(size=point.sz)+ 
  theme_classic()+
  theme( axis.title.x = element_text(size = axis.title.sz), 
         axis.title.y = element_text(size = axis.title.sz), 
         axis.text.x=element_text(size=axis.txt.sz, colour="black"),
         axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
         legend.position="none")+
  labs(x="", y="")+
  ylim(0.25, 1.5)+ 
  scale_x_discrete(labels=c("","Klein","","","Something Special",""))+
  scale_color_manual(values = Geno.colors.o)+ 
  stat_pvalue_manual(data=Tol_ScoreF_M1_lm.p,  y.position=1.1, step.increase=0.2, label="Sig", hide.ns=TRUE)


Tol_ScoreF_M4_SG.plot.fig<-ggplot(Tol_ScoreF_M4_SG, aes(x=Site.Geno, y=Score_Full.prop, colour=Genotype)) + 
  geom_errorbar(aes(ymin=Score_Full.prop-se, ymax=Score_Full.prop+se), width=cap.sz, linewidth=bar.sz)+
  geom_point(size=point.sz)+ 
  theme_classic()+
  theme( axis.title.x = element_text(size = axis.title.sz), 
         axis.title.y = element_text(size = axis.title.sz), 
         axis.text.x=element_text(size=axis.txt.sz, colour="black"),
         axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
         legend.position="none")+
  labs(x="", y="")+
  ylim(0.25, 1.5)+ 
  scale_x_discrete(labels=c("","Klein","","","Something Special",""))+
  scale_color_manual(values = Geno.colors.o)+ 
  stat_pvalue_manual(data=Tol_ScoreF_M4_lm.p,  y.position=1.1, step.increase=0.22, label="Sig", hide.ns=TRUE)


Tol_ScoreTP_W2_SG.plot.fig<-ggplot(Tol_ScoreTP_W2_SG, aes(x=Site.Geno, y=Score_TP.prop, colour=Genotype)) + 
  geom_errorbar(aes(ymin=Score_TP.prop-se, ymax=Score_TP.prop+se), width=cap.sz, linewidth=bar.sz)+
  geom_point(size=point.sz)+ 
  theme_classic()+
  theme( axis.title.x = element_text(size = axis.title.sz), 
         axis.title.y = element_text(size = axis.title.sz), 
         axis.text.x=element_text(size=axis.txt.sz, colour="black"),
         axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
         legend.position="none")+
  labs(x="", y="Proportion Color Retained (Split)")+
  ylim(0.25, 1.5)+ 
  scale_x_discrete(labels=c("","Klein","","","Something Special",""))+
  scale_color_manual(values = Geno.colors.o)+ 
  stat_pvalue_manual(data=Tol_ScoreTP_W2_lm.p,  y.position=1, step.increase=0.45, label="Sig", hide.ns=TRUE)


Tol_ScoreTP_M1_SG.plot.fig<-ggplot(Tol_ScoreTP_M1_SG, aes(x=Site.Geno, y=Score_TP.prop, colour=Genotype)) + 
  geom_errorbar(aes(ymin=Score_TP.prop-se, ymax=Score_TP.prop+se), width=cap.sz, linewidth=bar.sz)+
  geom_point(size=point.sz)+ 
  theme_classic()+
  theme( axis.title.x = element_text(size = axis.title.sz), 
         axis.title.y = element_text(size = axis.title.sz), 
         axis.text.x=element_text(size=axis.txt.sz, colour="black"),
         axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
         legend.position="none")+
  labs(x="", y="")+
  ylim(0.25, 1.5)+ 
  scale_x_discrete(labels=c("","Klein","","","Something Special",""))+
  scale_color_manual(values = Geno.colors.o)+ 
  stat_pvalue_manual(data=Tol_ScoreTP_M1_lm.p,  y.position=1.05, step.increase=0.3, label="Sig", hide.ns=TRUE)


Tol_ScoreTP_M4_SG.plot.fig<-ggplot(Tol_ScoreTP_M4_SG, aes(x=Site.Geno, y=Score_TP.prop, colour=Genotype)) + 
  geom_errorbar(aes(ymin=Score_TP.prop-se, ymax=Score_TP.prop+se), width=cap.sz, linewidth=bar.sz)+
  geom_point(size=point.sz)+ 
  theme_classic()+
  theme( axis.title.x = element_text(size = axis.title.sz), 
         axis.title.y = element_text(size = axis.title.sz), 
         axis.text.x=element_text(size=axis.txt.sz, colour="black"),
         axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
         legend.position="none")+
  labs(x="", y="")+
  ylim(0.25, 1.5)+ 
  scale_x_discrete(labels=c("","Klein","","","Something Special",""))+
  scale_color_manual(values = Geno.colors.o)+ 
  stat_pvalue_manual(data=Tol_ScoreTP_M4_lm.p,  y.position=1.1, step.increase=0.4, label="Sig", hide.ns=TRUE)

Figure S2

##Create Panel
Tolerance_fig<-plot_grid(Tol_Chl_W2_SG.plot.fig, Tol_Chl_M1_SG.plot.fig, Tol_Chl_M4_SG.plot.fig,
                  Tol_ScoreF_W2_SG.plot.fig, Tol_ScoreF_M1_SG.plot.fig, Tol_ScoreF_M4_SG.plot.fig,
                  Tol_ScoreTP_W2_SG.plot.fig, Tol_ScoreTP_M1_SG.plot.fig, Tol_ScoreTP_M4_SG.plot.fig,
                  Tol_Sym_W2_SG.plot.fig, Tol_Sym_M1_SG.plot.fig, Tol_Sym_M4_SG.plot.fig,
                        nrow=4, ncol=3, byrow=TRUE,
                        rel_widths=1,
                        rel_heights=c(1, 0.85, 0.85, 0.85), 
                        labels=c("A", "B", "C", 
                                 "D", "E", "F", 
                                 "G", "H", "I", 
                                 "J", "K", "L"), 
                        label_size=panel.lab.sz, 
                        label_fontface = "bold")

##Save Figure
ggsave(filename="Figures/FigureS2_Tolerance_Across_Metrics.png", plot=Tolerance_fig, dpi=300, width=14, height=20, units="in")

Figure 4 Contrasts Heatmap

##Save Figure
ggsave(filename="Figures/Figure4_Tolerance_Heatmap.png", plot=Tol_Pairs.plot, dpi=300, width=8, height=12, units="in")

Tables

Table S2 Linear Model Results

##Combine Results Tables
TableS2_Tol.lm.res<-rbind(Tol_Chl_W2_lm.res, Tol_Chl_M1_lm.res, Tol_Chl_M4_lm.res,
                        Tol_Sym_W2_lm.res, Tol_Sym_M1_lm.res, Tol_Sym_M4_lm.res,
                        Tol_ScoreF_W2_lm.res, Tol_ScoreF_M1_lm.res, Tol_ScoreF_M4_lm.res,
                    Tol_ScoreTP_W2_lm.res, Tol_ScoreTP_M1_lm.res, Tol_ScoreTP_M4_lm.res)

##Add a Season Variable
TableS2_Tol.lm.res$Season<-ifelse(TableS2_Tol.lm.res$TimeP=="W2", "Summer1", ifelse(TableS2_Tol.lm.res$TimeP=="M1", "Summer2", ifelse(TableS2_Tol.lm.res$TimeP=="M4", "Winter" , NA)))

##Organize
names(TableS2_Tol.lm.res)
TableS2_Tol.lm.res<-TableS2_Tol.lm.res[,c("TimeP", "Season", "Response", "Predictor", "DF", "Sum.Sq", "Mean.Sq", "F.value", "p.value", "EtaSq")]

#Round to 4 digits
TableS2_Tol.lm.res$Sum.Sq<-round(TableS2_Tol.lm.res$Sum.Sq, 4)
TableS2_Tol.lm.res$Mean.Sq<-round(TableS2_Tol.lm.res$Mean.Sq, 4)
TableS2_Tol.lm.res$F.value<-round(TableS2_Tol.lm.res$F.value, 4)
TableS2_Tol.lm.res$p.value<-round(TableS2_Tol.lm.res$p.value, 4)
TableS2_Tol.lm.res$EtaSq<-round(TableS2_Tol.lm.res$EtaSq, 4)

##Write Out Table
write.csv(TableS2_Tol.lm.res, "Tables/TableS2_Tolerance_LM_Results.csv", row.names=FALSE)

Table S3 Pairwise Comparison Results

##Pairwise Results Table
TableS3_Tol.pairwise<-Tol_contrasts

##Add a Season Variable
TableS3_Tol.pairwise$Season<-ifelse(TableS3_Tol.pairwise$TimeP=="W2", "Summer1", ifelse(TableS3_Tol.pairwise$TimeP=="M1", "Summer2", ifelse(TableS3_Tol.pairwise$TimeP=="M4", "Winter" , NA)))

##Re-order by Seasonal Timepoint
TableS3_Tol.pairwise<- TableS3_Tol.pairwise %>% arrange(as.numeric(TimeP))

##Organize
names(TableS3_Tol.pairwise)
TableS3_Tol.pairwise<-TableS3_Tol.pairwise[,c("TimeP", "Season", "Response", "Contrast", "Estimate", "SE", "df", "t.ratio", "p")]
TableS3_Tol.pairwise<-TableS3_Tol.pairwise %>% dplyr::rename( DF = df) %>% dplyr::rename( p.value = p)

#Round to 4 digits
TableS3_Tol.pairwise$Estimate<-round(TableS3_Tol.pairwise$Estimate, 4)
TableS3_Tol.pairwise$SE<-round(TableS3_Tol.pairwise$SE, 4)
TableS3_Tol.pairwise$t.ratio<-round(TableS3_Tol.pairwise$t.ratio, 4)
TableS3_Tol.pairwise$p.value<-round(TableS3_Tol.pairwise$p.value, 4)

##Write Out Table
write.csv(TableS3_Tol.pairwise, "Tables/TableS3_Tolerance_Pairwise_Results.csv", row.names=FALSE)
LS0tDQp0aXRsZTogIlRoZXJtYWwgVG9sZXJhbmNlIHdpdGggQ29sb3IgU2NvcmUgYW5kIEJsZWFjaGluZyBNZXRyaWNzIg0KYXV0aG9yOiAiU2VyZW5hIEhhY2tlcm90dCBhbmQgTGF1cmVuIEdyZWdvcnkiDQpkYXRlOiAiNy8xOS8yMDI0Ig0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIHRvYzogeWVzDQogICAgZGZfcHJpbnQ6IHBhZ2VkDQogIGh0bWxfbm90ZWJvb2s6DQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZmxvYXQ6IHllcw0KLS0tDQoNCiMgU2V0dXANCmBgYHtyIFNldHVwLCBpbmNsdWRlID0gRkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsIHdhcm5pbmcgPSBGQUxTRSwgbWVzc2FnZSA9IEZBTFNFKQ0KYGBgDQoNCg0KIyMjIExvYWQgUGFja2FnZXMNCmBgYHtyfQ0KIyNJbnN0YWxsIFBhY2thZ2VzIGlmIE5lZWRlZA0KaWYgKCFyZXF1aXJlKCJnZ3Bsb3QyIikpIGluc3RhbGwucGFja2FnZXMoImdncGxvdDIiKQ0KaWYgKCFyZXF1aXJlKCJlZmZlY3RzaXplIikpIGluc3RhbGwucGFja2FnZXMoImVmZmVjdHNpemUiKQ0KaWYgKCFyZXF1aXJlKCJlbW1lYW5zIikpIGluc3RhbGwucGFja2FnZXMoImVtbWVhbnMiKQ0KaWYgKCFyZXF1aXJlKCJkcGx5ciIpKSBpbnN0YWxsLnBhY2thZ2VzKCJkcGx5ciIpDQppZiAoIXJlcXVpcmUoInRpZHlyIikpIGluc3RhbGwucGFja2FnZXMoInRpZHlyIikNCmlmICghcmVxdWlyZSgiUm1pc2MiKSkgaW5zdGFsbC5wYWNrYWdlcygiUm1pc2MiKQ0KaWYgKCFyZXF1aXJlKCJnZ3B1YnIiKSkgaW5zdGFsbC5wYWNrYWdlcygiZ2dwdWJyIikNCmlmICghcmVxdWlyZSgiY293cGxvdCIpKSBpbnN0YWxsLnBhY2thZ2VzKCJjb3dwbG90IikNCmlmICghcmVxdWlyZSgiZ3JpZEdyYXBoaWNzIikpIGluc3RhbGwucGFja2FnZXMoImdyaWRHcmFwaGljcyIpDQppZiAoIXJlcXVpcmUoInRpZHlyIikpIGluc3RhbGwucGFja2FnZXMoInRpZHlyIikNCg0KIyNMb2FkIFBhY2thZ2VzDQpsaWJyYXJ5KGdncGxvdDIpICNSZXF1aXJlZCBmb3IgcGxvdHRpbmcNCmxpYnJhcnkoZWZmZWN0c2l6ZSkgI1JlcXVpcmVkIGZvciBldGFfc3F1YXJlZCBlZmZlY3Qgc2l6ZXMNCmxpYnJhcnkoZW1tZWFucykgI1JlcXVpcmVkIGZvciBwYWlyd2lzZSBjb21wYXJpc29ucw0KbGlicmFyeShkcGx5cikgI1JlcXVpcmVkIHRvIHNlcGVyYXRlIGNvbHVtbnMgaW4gZGF0YWZyYW1lDQpsaWJyYXJ5KHRpZHlyKSAjUmVxdWlyZWQgZm9yIGRhdGEgb3JnYW5pemF0aW9uDQpsaWJyYXJ5KFJtaXNjKSAjUmVxdWlyZWQgZm9yIHN1bW1hcnlTRSBmb3Igc3VtbWFyeSBzdGF0aXN0aWNzDQpsaWJyYXJ5KGdncHVicikgI1JlcXVpcmVkIGZvciBhZGRpbmcgcGFpcndpc2UgcC12YWx1ZXMgdG8gcGxvdHMgd2l0aCBzdGF0X3B2YWx1ZV9tYW51YWwgDQpsaWJyYXJ5KGNvd3Bsb3QpICNSZXF1aXJlZCBmb3IgYXJyYW5naW5nIGdncGxvdHMgDQpsaWJyYXJ5KGdyaWRHcmFwaGljcykgI1JlcXVpcmVkIGZvciBhZGRpbmcgbGFiZWxzIHRvIGFycmFuZ2VkIHBsb3RzDQpsaWJyYXJ5KHRpZHlyKSAjUmVxdWlyZWQgZm9yIHJlc2hhcGluZyBkYXRhZnJvbSBmcm9tIGEgd2lkZSB0byBsb25nIGZvcm1hdC4NCmBgYA0KTm90ZTogUnVuICJHcmFwaGluZyBQYXJhbWV0ZXJzIiBzZWN0aW9uIGZyb20gMDFfRXhwZXJpbWVudGFsU2V0dXAuUiBmaWxlDQoNCg0KIyMjIExvYWQgYW5kIE9yZ2FuaXplIERhdGENCk5vdGU6IEZ1bGwgRGF0YSB3aXRoIEJsZWFjaGluZyBNZXRyaWNzIGFuZCBDb2xvciBTY29yZXMgY3JlYXRlZCBpbiAwNF9Nb2RlbHMuUiBmaWxlDQpgYGB7cn0NCiNMb2FkIERhdGENCkZ1bGxEYXRhPC1yZWFkLmNzdigiT3V0cHV0cy9GdWxsRGF0YS5jc3YiLCBoZWFkZXI9VFJVRSkNCg0KDQojU2V0IGZhY3RvciB2YXJpYWJsZXMgDQpGdWxsRGF0YSRUaW1lUDwtZmFjdG9yKEZ1bGxEYXRhJFRpbWVQLCBsZXZlbHM9YygiVzIiLCAiTTEiLCAiTTQiKSwgb3JkZXJlZD1UUlVFKQ0KRnVsbERhdGEkU2l0ZTwtZmFjdG9yKEZ1bGxEYXRhJFNpdGUsIGxldmVscz1jKCJLTCIsICJTUyIpLCBvcmRlcmVkPVRSVUUpDQpGdWxsRGF0YSRHZW5vdHlwZTwtZmFjdG9yKEZ1bGxEYXRhJEdlbm90eXBlLCBsZXZlbHM9YygiQUMxMCIsICJBQzEyIiwgIkFDOCIpLCBvcmRlcmVkPVRSVUUpDQpGdWxsRGF0YSRUcmVhdG1lbnQ8LWZhY3RvcihGdWxsRGF0YSRUcmVhdG1lbnQsIGxldmVscz1jKCJDb250cm9sIiwgIkhlYXQiKSwgb3JkZXJlZD1UUlVFKQ0KRnVsbERhdGEkVHJlYXQ8LWZhY3RvcihGdWxsRGF0YSRUcmVhdCwgbGV2ZWxzPWMoIkMiLCAiSCIpLCBvcmRlcmVkPVRSVUUpDQpGdWxsRGF0YSRTZWFzPC1mYWN0b3IoRnVsbERhdGEkU2VhcywgbGV2ZWxzPWMoIlN1bW1lcjEiLCAiU3VtbWVyMiIsICJXaW50ZXIiKSwgb3JkZXJlZD1UUlVFKQ0KYGBgDQoNCg0KIyBQZXJjZW50IFJldGVudGlvbg0KDQojIyMgU3Vic2V0IFRoZXJtYWwgQXNzYXkgRGF0YSBieSBUcmVhdG1lbnQNCmBgYHtyfQ0KIyNDb250cm9sDQpGdWxsRGF0YV9DPC1zdWJzZXQoRnVsbERhdGEsIFRyZWF0PT0iQyIpDQoNCiMjSGVhdGVkDQpGdWxsRGF0YV9IPC1zdWJzZXQoRnVsbERhdGEsIFRyZWF0PT0iSCIpDQpgYGANCg0KDQojIyMgQ2FsY3VsYXRlIFBlcmNlbnQgUmV0ZW50aW9uDQpDYWxjdWxhdGluZyByZXRlbnRpb24gYXMgcHJvcG9ydGlvbiByZW1haW5pbmcgcmVsYXRpdmUgdG8gY29ycmVzcG9uZGluZyBjb250cm9sIGxldmVscyAoMC0xKSBmb3IgZWFjaCBzaXRlIGFuZCBnZW5vdHlwZSBhdCBlYWNoIHRpbWVwb2ludC4NCmBgYHtyfQ0KIyNDYWxjdWxhdGUgYXZlcmFnZXMgZm9yIENvbnRyb2wgVHJlYXRtZW50IGZvciBlYWNoIFNpdGUsIEdlbm90eXBlLCBUaW1lcG9pbnQsIGFuZCBTZWFzb24NCm5hbWVzKEZ1bGxEYXRhX0MpDQpGdWxsRGF0YV9DLmE8LWFnZ3JlZ2F0ZShGdWxsRGF0YV9DWyxjKDEwOjExLCAxMzoxNCldLCBsaXN0KEZ1bGxEYXRhX0MkU2l0ZSwgRnVsbERhdGFfQyRHZW5vdHlwZSwgRnVsbERhdGFfQyRUaW1lUCwgRnVsbERhdGFfQyRTZWFzKSwgbWVhbiwgbmEuYWN0aW9uID0gbmEub21pdCkNCm5hbWVzKEZ1bGxEYXRhX0MuYSlbMTo0XTwtYygiU2l0ZSIsICJHZW5vdHlwZSIsICJUaW1lUCIsICJTZWFzIikNCm5hbWVzKEZ1bGxEYXRhX0MuYSlbNTo4XTwtcGFzdGUobmFtZXMoRnVsbERhdGFfQylbYygxMDoxMSwgMTM6MTQpXSwgIkMiLCBzZXA9Il8iKQ0KDQojI01lcmdlIENvbnRyb2wgQXZlcmFnZXMgd2l0aCBIZWF0ZWQgU2FtcGxlcw0KI01lcmdlcyBieSBTaXRlLCBHZW5vdHlwZSwgVGltZXBvaW50LCBhbmQgU2Vhc29uDQpUb2xEYXRhPC1tZXJnZShGdWxsRGF0YV9ILCBGdWxsRGF0YV9DLmEsIGFsbC54PVRSVUUgKQ0KDQojI0NhbGN1bGF0ZSBQcm9wb3J0aW9uIFJldGFpbmVkIGZvciBlYWNoIEJsZWFjaGluZyBNZXRyaWMgcmVsYXRpdmUgdG8gQ29udHJvbA0KVG9sRGF0YSRTY29yZV9GdWxsLnByb3A8LXJvdW5kKChUb2xEYXRhJFNjb3JlX0Z1bGwvVG9sRGF0YSRTY29yZV9GdWxsX0MpLCA0KQ0KVG9sRGF0YSRTY29yZV9UUC5wcm9wPC1yb3VuZCgoVG9sRGF0YSRTY29yZV9UUC9Ub2xEYXRhJFNjb3JlX1RQX0MpLCA0KQ0KVG9sRGF0YSRDaGwucHJvcDwtcm91bmQoKFRvbERhdGEkQ2hsX3VnLmNtMi9Ub2xEYXRhJENobF91Zy5jbTJfQyksIDQpDQpUb2xEYXRhJFN5bS5wcm9wPC1yb3VuZCgoVG9sRGF0YSRTeW0xMC42X2NtMi9Ub2xEYXRhJFN5bTEwLjZfY20yX0MpLCA0KQ0KDQojI1NldCB2YWx1ZXMgPjEgdG8gMQ0KVG9sRGF0YSRTY29yZV9GdWxsLnByb3Bbd2hpY2goVG9sRGF0YSRTY29yZV9GdWxsLnByb3A+MSldPC0xLjAwMDANClRvbERhdGEkU2NvcmVfVFAucHJvcFt3aGljaChUb2xEYXRhJFNjb3JlX1RQLnByb3A+MSldPC0xLjAwMDANClRvbERhdGEkQ2hsLnByb3Bbd2hpY2goVG9sRGF0YSRDaGwucHJvcD4xKV08LTEuMDAwMA0KVG9sRGF0YSRTeW0ucHJvcFt3aGljaChUb2xEYXRhJFN5bS5wcm9wPjEpXTwtMS4wMDAwDQoNCiMjQ3JlYXRlIFNpdGUgYW5kIEdlbm90eXBlIFZhcmlhYmxlDQpUb2xEYXRhJFNpdGUuR2VubzwtcGFzdGUoVG9sRGF0YSRTaXRlLCBUb2xEYXRhJEdlbm90eXBlLCBzZXA9Il8iKQ0KYGBgDQoNCg0KIyMjIFN1YnNldCBieSBUaW1lcG9pbnQNCmBgYHtyfQ0KVG9sRGF0YV9XMjwtc3Vic2V0KFRvbERhdGEsIFRpbWVQPT0iVzIiKQ0KVG9sRGF0YV9NMTwtc3Vic2V0KFRvbERhdGEsIFRpbWVQPT0iTTEiKQ0KVG9sRGF0YV9NNDwtc3Vic2V0KFRvbERhdGEsIFRpbWVQPT0iTTQiKQ0KYGBgDQoNCg0KDQojIFRoZXJtYWwgVG9sZXJhbmNlIENobG9yb3BoeWxsDQoNCiMjIEZ1bGwgU2V0DQoNCiMjIyBSdW4gTW9kZWwNCmBgYHtyfQ0KIyNDaGVjayBub3JtYWxpdHkNCmhpc3QoVG9sRGF0YSRDaGwucHJvcCkNCnNoYXBpcm8udGVzdChUb2xEYXRhJENobC5wcm9wKQ0KI05vcm1hbA0KDQojI01vZGVsIGFzIGEgZnVuY3Rpb24gb2YgU2l0ZSBhbmQgR2Vub3R5cGUgYW5kIFRpbWVwb2ludA0KVG9sX0NobF9sbTwtbG0oQ2hsLnByb3B+U2l0ZStHZW5vdHlwZStUaW1lUCsgU2l0ZTpHZW5vdHlwZSArIFNpdGU6VGltZVAgKyBHZW5vdHlwZTpUaW1lUCwgZGF0YT1Ub2xEYXRhKQ0KDQpgYGANCg0KDQojIyMjIENoZWNrIFJlc2lkdWFscw0KYGBge3J9DQojI0NoZWNrIE5vcm1hbGl0eSBvZiBSZXNpZHVhbHMNCiNEaXN0cmlidXRpb24gDQpwbG90KGRlbnNpdHkocmVzaWQoVG9sX0NobF9sbSkpKQ0KDQojUS1RIHBsb3QNCnFxbm9ybShyZXNpZChUb2xfQ2hsX2xtKSk7IHFxbGluZShyZXNpZChUb2xfQ2hsX2xtKSkNCg0KIyNDaGVjayBWYXJpYW5jZSBvZiBSZXNpZHVhbHMgYWNyb3NzIEZpdHRlZCBWYWx1ZXMNCnBsb3QoZml0dGVkKFRvbF9DaGxfbG0pLCByZXNpZChUb2xfQ2hsX2xtKSkNCg0KYGBgDQoNCg0KIyMjIE1vZGVsIFJlc3VsdHMNCg0KYGBge3J9DQojTW9kZWwgUmVzdWx0cw0Kc3VtbWFyeShUb2xfQ2hsX2xtKQ0KYW5vdmEoVG9sX0NobF9sbSkNCg0KI0VmZmVjdCBTaXplIG9mIFByZWRpY3RvcnMNCmV0YV9zcXVhcmVkKFRvbF9DaGxfbG0sIHBhcnRpYWw9RkFMU0UpDQoNCiMjU2F2ZSBtb2RlbCByZXN1bHRzDQpUb2xfQ2hsX2xtLnJlczwtZGF0YS5mcmFtZShhbm92YShUb2xfQ2hsX2xtKSkNClRvbF9DaGxfbG0ucmVzJFByZWRpY3Rvcjwtcm93bmFtZXMoVG9sX0NobF9sbS5yZXMpDQpUb2xfQ2hsX2xtLnJlcyRFdGFTcTwtYyhldGFfc3F1YXJlZChUb2xfQ2hsX2xtLCBwYXJ0aWFsPUZBTFNFKSRFdGEyLCBOQSkNClRvbF9DaGxfbG0ucmVzJFJlc3BvbnNlPC1yZXAoIkNobG9yb3BoeWxsIiwgbnJvdyhUb2xfQ2hsX2xtLnJlcykpDQpUb2xfQ2hsX2xtLnJlczwtVG9sX0NobF9sbS5yZXMgJT4lIGRwbHlyOjpyZW5hbWUoIHAudmFsdWUgPSAiUHIuLkYuIiwgREY9ICJEZiIpDQoNCmBgYA0KU3Ryb25nIGluZmx1ZW5jZSBvZiBUaW1lcG9pbnQsIGluY2x1ZGluZyBpbnRlcmFjdGlvbnMgd2l0aCBtYWluIHZhcmlhYmxlcyBvZiBpbnRlcmVzdCwgU2l0ZSBhbmQgR2Vub3R5cGUuIFdpbGwgYW5hbHl6ZSBlYWNoIFRpbWVwb2ludCBpbmRpdmlkdWFsbHkuIA0KDQoNCiMjIENobCBTdW1tZXIgMSBUaW1lcG9pbnQgVzIgDQoNCiMjIyBSdW4gTW9kZWwNCmBgYHtyfQ0KIyNDaGVjayBub3JtYWxpdHkNCmhpc3QoVG9sRGF0YV9XMiRDaGwucHJvcCkNCnNoYXBpcm8udGVzdChUb2xEYXRhX1cyJENobC5wcm9wKQ0KI05vcm1hbA0KDQojI01vZGVsIGFzIGEgZnVuY3Rpb24gb2YgU2l0ZSBhbmQgR2Vub3R5cGUNClRvbF9DaGxfVzJfbG08LWxtKENobC5wcm9wflNpdGUrR2Vub3R5cGUrU2l0ZTpHZW5vdHlwZSwgZGF0YT1Ub2xEYXRhX1cyKQ0KDQpgYGANCg0KDQojIyMjIENoZWNrIFJlc2lkdWFscw0KYGBge3J9DQojI0NoZWNrIE5vcm1hbGl0eSBvZiBSZXNpZHVhbHMNCiNEaXN0cmlidXRpb24gDQpwbG90KGRlbnNpdHkocmVzaWQoVG9sX0NobF9XMl9sbSkpKQ0KDQojUS1RIHBsb3QNCnFxbm9ybShyZXNpZChUb2xfQ2hsX1cyX2xtKSk7IHFxbGluZShyZXNpZChUb2xfQ2hsX1cyX2xtKSkNCg0KIyNDaGVjayBWYXJpYW5jZSBvZiBSZXNpZHVhbHMgYWNyb3NzIEZpdHRlZCBWYWx1ZXMNCnBsb3QoZml0dGVkKFRvbF9DaGxfVzJfbG0pLCByZXNpZChUb2xfQ2hsX1cyX2xtKSkNCg0KYGBgDQoNCg0KIyMjIE1vZGVsIFJlc3VsdHMNCg0KIyMjIyBPdmVyYWxsDQpgYGB7cn0NCiNNb2RlbCBSZXN1bHRzDQpzdW1tYXJ5KFRvbF9DaGxfVzJfbG0pDQphbm92YShUb2xfQ2hsX1cyX2xtKQ0KDQojRWZmZWN0IFNpemUgb2YgUHJlZGljdG9ycw0KZXRhX3NxdWFyZWQoVG9sX0NobF9XMl9sbSwgcGFydGlhbD1GQUxTRSkNCg0KIyNTYXZlIG1vZGVsIHJlc3VsdHMNClRvbF9DaGxfVzJfbG0ucmVzPC1kYXRhLmZyYW1lKGFub3ZhKFRvbF9DaGxfVzJfbG0pKQ0KVG9sX0NobF9XMl9sbS5yZXMkUHJlZGljdG9yPC1yb3duYW1lcyhUb2xfQ2hsX1cyX2xtLnJlcykNClRvbF9DaGxfVzJfbG0ucmVzJEV0YVNxPC1jKGV0YV9zcXVhcmVkKFRvbF9DaGxfVzJfbG0sIHBhcnRpYWw9RkFMU0UpJEV0YTIsIE5BKQ0KVG9sX0NobF9XMl9sbS5yZXMkUmVzcG9uc2U8LXJlcCgiQ2hsb3JvcGh5bGwiLCBucm93KFRvbF9DaGxfVzJfbG0ucmVzKSkNClRvbF9DaGxfVzJfbG0ucmVzJFRpbWVQPC1yZXAoIlcyIiwgbnJvdyhUb2xfQ2hsX1cyX2xtLnJlcykpDQpUb2xfQ2hsX1cyX2xtLnJlczwtVG9sX0NobF9XMl9sbS5yZXMgJT4lIGRwbHlyOjpyZW5hbWUoIHAudmFsdWUgPSAiUHIuLkYuIiwgREY9ICJEZiIpDQoNCmBgYA0KDQpTaWduaWZpY2FudCBlZmZlY3Qgb2YgR2Vub3R5cGUuIFN0aWxsIGNoZWNraW5nIFNpdGUqR2Vub3R5cGUgZm9yIGNvbXBhcmFiaWxpdHkgYWNyb3NzIFRpbWVwb2ludHMuDQoNCg0KIyMjIyBQYWlyd2lzZQ0KYGBge3J9DQojUGFpcndpc2UgY29tcGFyaXNvbnMgYWNyb3NzOg0KDQojR2Vub3R5cGVzIHdpdGhpbiBTaXRlcw0KZW1tZWFucyhUb2xfQ2hsX1cyX2xtLCBwYWlyd2lzZX5HZW5vdHlwZSB8IFNpdGUpDQoNCiNTaXRlcyB3aXRoaW4gR2Vub3R5cGVzDQplbW1lYW5zKFRvbF9DaGxfVzJfbG0sIHBhaXJ3aXNlflNpdGUgfCBHZW5vdHlwZSkNCg0KIyNTYXZlIHAtdmFsdWVzDQoNCiNHZW5vdHlwZXMgd2l0aGluIFNpdGVzDQpUb2xfQ2hsX1cyX2xtLmdlbm88LWRhdGEuZnJhbWUoZW1tZWFucyhUb2xfQ2hsX1cyX2xtLCBwYWlyd2lzZX5HZW5vdHlwZSB8IFNpdGUpJGNvbnRyYXN0cykNClRvbF9DaGxfVzJfbG0uZ2VubzwtVG9sX0NobF9XMl9sbS5nZW5vICU+JSBzZXBhcmF0ZShjb2w9Y29udHJhc3QsIGludG89YygiZ3JvdXAxIiwgImdyb3VwMiIpLCBzZXA9IiAtICIsIHJlbW92ZT1UUlVFKQ0KVG9sX0NobF9XMl9sbS5nZW5vJGdyb3VwMTwtcGFzdGUoVG9sX0NobF9XMl9sbS5nZW5vJFNpdGUsIFRvbF9DaGxfVzJfbG0uZ2VubyRncm91cDEsIHNlcD0iXyIpDQpUb2xfQ2hsX1cyX2xtLmdlbm8kZ3JvdXAyPC1wYXN0ZShUb2xfQ2hsX1cyX2xtLmdlbm8kU2l0ZSwgVG9sX0NobF9XMl9sbS5nZW5vJGdyb3VwMiwgc2VwPSJfIikNCg0KI1NpdGVzIHdpdGhpbiBHZW5vdHlwZXMNClRvbF9DaGxfVzJfbG0uc2l0ZTwtZGF0YS5mcmFtZShlbW1lYW5zKFRvbF9DaGxfVzJfbG0sIHBhaXJ3aXNlflNpdGUgfCBHZW5vdHlwZSkkY29udHJhc3RzKQ0KVG9sX0NobF9XMl9sbS5zaXRlPC1Ub2xfQ2hsX1cyX2xtLnNpdGUgJT4lIHNlcGFyYXRlKGNvbD1jb250cmFzdCwgaW50bz1jKCJncm91cDEiLCAiZ3JvdXAyIiksIHNlcD0iIC0gIiwgcmVtb3ZlPVRSVUUpDQpUb2xfQ2hsX1cyX2xtLnNpdGUkZ3JvdXAxPC1wYXN0ZShUb2xfQ2hsX1cyX2xtLnNpdGUkZ3JvdXAxLCBUb2xfQ2hsX1cyX2xtLnNpdGUkR2Vub3R5cGUsIHNlcD0iXyIpDQpUb2xfQ2hsX1cyX2xtLnNpdGUkZ3JvdXAyPC1wYXN0ZShUb2xfQ2hsX1cyX2xtLnNpdGUkZ3JvdXAyLCBUb2xfQ2hsX1cyX2xtLnNpdGUkR2Vub3R5cGUsIHNlcD0iXyIpDQoNCiNGdWxsIGxpc3Qgb2YgcC12YWx1ZXMNClRvbF9DaGxfVzJfbG0ucDwtcmJpbmQoVG9sX0NobF9XMl9sbS5nZW5vWyxjKDE6Miw0OjgpXSwgVG9sX0NobF9XMl9sbS5zaXRlWyxjKDE6Miw0OjgpXSkNClRvbF9DaGxfVzJfbG0ucDwtVG9sX0NobF9XMl9sbS5wICU+JSBkcGx5cjo6cmVuYW1lKCBwID0gcC52YWx1ZSkNCg0KI0FkZCBTaWduaWZpY2FuY2UgTGV2ZWxzDQpUb2xfQ2hsX1cyX2xtLnAkU2lnPC1pZmVsc2UoVG9sX0NobF9XMl9sbS5wJHA8MC4wMDEsICIqKioiLCBpZmVsc2UoVG9sX0NobF9XMl9sbS5wJHA8MC4wMSwgIioqIiwgaWZlbHNlKFRvbF9DaGxfVzJfbG0ucCRwPDAuMDUsICIqIiwgTkEpKSkNCg0KI1NwZWNpZnkgUmVzcG9uc2UgYW5kIFRpbWVwb2ludA0KVG9sX0NobF9XMl9sbS5wJFJlc3BvbnNlPC1yZXAoIkNobG9yb3BoeWxsIiwgbnJvdyhUb2xfQ2hsX1cyX2xtLnApKQ0KVG9sX0NobF9XMl9sbS5wJFRpbWVQPC1yZXAoIlcyIiwgbnJvdyhUb2xfQ2hsX1cyX2xtLnApKQ0KDQpgYGANCg0KDQojIyMgUGxvdCBSZXRlbnRpb24gYnkgU2l0ZSBhbmQgR2Vub3R5cGUNCmBgYHtyfQ0KIyNTdW1tYXJ5IHN0YXRpc3RpY3MgYnkgU2l0ZSBhbmQgR2Vub3R5cGUNClRvbF9DaGxfVzJfU0c8LXN1bW1hcnlTRShUb2xEYXRhX1cyLCBtZWFzdXJldmFyPSJDaGwucHJvcCIsIGdyb3VwdmFycz1jKCJTaXRlLkdlbm8iLCAiU2l0ZSIsICJHZW5vdHlwZSIpLCBuYS5ybT1UUlVFKQ0KDQojI1Bsb3QgQXZlcmFnZSBSZXRlbnRpb24gYWNyb3NzIFRyZWF0bWVudHMNClRvbF9DaGxfVzJfU0cucGxvdDwtZ2dwbG90KFRvbF9DaGxfVzJfU0csIGFlcyh4PVNpdGUuR2VubywgeT1DaGwucHJvcCwgY29sb3VyPUdlbm90eXBlKSkgKyANCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1DaGwucHJvcC1zZSwgeW1heD1DaGwucHJvcCtzZSksIHdpZHRoPWNhcC5zeiwgbGluZXdpZHRoPWJhci5zeikrDQogIGdlb21fcG9pbnQoc2l6ZT1wb2ludC5zeikrIA0KICAgZ2d0aXRsZSgiQ2hsb3JvcGh5bGwgUmV0ZW50aW9uIikrDQogIHRoZW1lX2NsYXNzaWMoKSsNCiAgdGhlbWUoIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIA0KICAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSBheGlzLnRpdGxlLnN6KSwgDQogICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksDQogICAgICAgIGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksIA0KICAgICAgICBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoc2l6ZT1sZWcudHh0LnN6KSwNCiAgICAgICAgbGVnZW5kLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPWxlZy50aXRsZS5zeiksIA0KICAgICAgICBsZWdlbmQuYm94LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoY29sb3IgPSAiYmxhY2siKSwNCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJib3R0b20iLCANCiAgICAgICAgbGVnZW5kLmRpcmVjdGlvbj0iaG9yaXpvbnRhbCIsDQogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHBsb3QudGl0bGUuc3osIGNvbG91cj0iYmxhY2siLCBoanVzdCA9IDAuNSkpKw0KICBsYWJzKHg9IiIsIHk9IlByb3BvcnRpb24gUmV0YWluZWQiKSsNCiAgeWxpbSgwLCAxKSsgDQogIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzPWMoIiIsIktsZWluIiwiIiwiIiwiU29tZXRoaW5nIFNwZWNpYWwiLCIiKSkrDQogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBHZW5vLmNvbG9ycy5vKSsgDQogIHN0YXRfcHZhbHVlX21hbnVhbChkYXRhPVRvbF9DaGxfVzJfbG0ucCwgIHkucG9zaXRpb249MC40LCBzdGVwLmluY3JlYXNlPTAuMjUsIGxhYmVsPSJTaWciLCBoaWRlLm5zPVRSVUUpOyBUb2xfQ2hsX1cyX1NHLnBsb3QNCg0KYGBgDQoNCg0KIyMgQ2hsIFN1bW1lciAyIFRpbWVwb2ludCBNMQ0KDQojIyMgUnVuIE1vZGVsDQpgYGB7cn0NCiMjQ2hlY2sgbm9ybWFsaXR5DQpoaXN0KFRvbERhdGFfTTEkQ2hsLnByb3ApDQpzaGFwaXJvLnRlc3QoVG9sRGF0YV9NMSRDaGwucHJvcCkNCiNOb3JtYWwNCg0KIyNNb2RlbCBhcyBhIGZ1bmN0aW9uIG9mIFNpdGUgYW5kIEdlbm90eXBlDQpUb2xfQ2hsX00xX2xtPC1sbShDaGwucHJvcH5TaXRlK0dlbm90eXBlK1NpdGU6R2Vub3R5cGUsIGRhdGE9VG9sRGF0YV9NMSkNCg0KYGBgDQoNCg0KIyMjIyBDaGVjayBSZXNpZHVhbHMNCmBgYHtyfQ0KIyNDaGVjayBOb3JtYWxpdHkgb2YgUmVzaWR1YWxzDQojRGlzdHJpYnV0aW9uIA0KcGxvdChkZW5zaXR5KHJlc2lkKFRvbF9DaGxfTTFfbG0pKSkNCg0KI1EtUSBwbG90DQpxcW5vcm0ocmVzaWQoVG9sX0NobF9NMV9sbSkpOyBxcWxpbmUocmVzaWQoVG9sX0NobF9NMV9sbSkpDQoNCiMjQ2hlY2sgVmFyaWFuY2Ugb2YgUmVzaWR1YWxzIGFjcm9zcyBGaXR0ZWQgVmFsdWVzDQpwbG90KGZpdHRlZChUb2xfQ2hsX00xX2xtKSwgcmVzaWQoVG9sX0NobF9NMV9sbSkpDQoNCmBgYA0KDQoNCiMjIyBNb2RlbCBSZXN1bHRzDQoNCiMjIyMgT3ZlcmFsbA0KYGBge3J9DQojTW9kZWwgUmVzdWx0cw0Kc3VtbWFyeShUb2xfQ2hsX00xX2xtKQ0KYW5vdmEoVG9sX0NobF9NMV9sbSkNCg0KI0VmZmVjdCBTaXplIG9mIFByZWRpY3RvcnMNCmV0YV9zcXVhcmVkKFRvbF9DaGxfTTFfbG0sIHBhcnRpYWw9RkFMU0UpDQoNCiMjU2F2ZSBtb2RlbCByZXN1bHRzDQpUb2xfQ2hsX00xX2xtLnJlczwtZGF0YS5mcmFtZShhbm92YShUb2xfQ2hsX00xX2xtKSkNClRvbF9DaGxfTTFfbG0ucmVzJFByZWRpY3Rvcjwtcm93bmFtZXMoVG9sX0NobF9NMV9sbS5yZXMpDQpUb2xfQ2hsX00xX2xtLnJlcyRFdGFTcTwtYyhldGFfc3F1YXJlZChUb2xfQ2hsX00xX2xtLCBwYXJ0aWFsPUZBTFNFKSRFdGEyLCBOQSkNClRvbF9DaGxfTTFfbG0ucmVzJFJlc3BvbnNlPC1yZXAoIkNobG9yb3BoeWxsIiwgbnJvdyhUb2xfQ2hsX00xX2xtLnJlcykpDQpUb2xfQ2hsX00xX2xtLnJlcyRUaW1lUDwtcmVwKCJNMSIsIG5yb3coVG9sX0NobF9NMV9sbS5yZXMpKQ0KVG9sX0NobF9NMV9sbS5yZXM8LVRvbF9DaGxfTTFfbG0ucmVzICU+JSBkcGx5cjo6cmVuYW1lKCBwLnZhbHVlID0gIlByLi5GLiIsIERGPSAiRGYiKQ0KDQpgYGANCg0KU2lnbmlmaWNhbnQgZWZmZWN0IG9mIEdlbm90eXBlLiBTdGlsbCBjaGVja2luZyBTaXRlKkdlbm90eXBlIGZvciBjb21wYXJhYmlsaXR5IGFjcm9zcyBUaW1lcG9pbnRzLg0KDQoNCiMjIyMgUGFpcndpc2UNCmBgYHtyfQ0KI1BhaXJ3aXNlIGNvbXBhcmlzb25zIGFjcm9zczoNCg0KI0dlbm90eXBlcyB3aXRoaW4gU2l0ZXMNCmVtbWVhbnMoVG9sX0NobF9NMV9sbSwgcGFpcndpc2V+R2Vub3R5cGUgfCBTaXRlKQ0KDQojU2l0ZXMgd2l0aGluIEdlbm90eXBlcw0KZW1tZWFucyhUb2xfQ2hsX00xX2xtLCBwYWlyd2lzZX5TaXRlIHwgR2Vub3R5cGUpDQoNCiMjU2F2ZSBwLXZhbHVlcw0KDQojR2Vub3R5cGVzIHdpdGhpbiBTaXRlcw0KVG9sX0NobF9NMV9sbS5nZW5vPC1kYXRhLmZyYW1lKGVtbWVhbnMoVG9sX0NobF9NMV9sbSwgcGFpcndpc2V+R2Vub3R5cGUgfCBTaXRlKSRjb250cmFzdHMpDQpUb2xfQ2hsX00xX2xtLmdlbm88LVRvbF9DaGxfTTFfbG0uZ2VubyAlPiUgc2VwYXJhdGUoY29sPWNvbnRyYXN0LCBpbnRvPWMoImdyb3VwMSIsICJncm91cDIiKSwgc2VwPSIgLSAiLCByZW1vdmU9VFJVRSkNClRvbF9DaGxfTTFfbG0uZ2VubyRncm91cDE8LXBhc3RlKFRvbF9DaGxfTTFfbG0uZ2VubyRTaXRlLCBUb2xfQ2hsX00xX2xtLmdlbm8kZ3JvdXAxLCBzZXA9Il8iKQ0KVG9sX0NobF9NMV9sbS5nZW5vJGdyb3VwMjwtcGFzdGUoVG9sX0NobF9NMV9sbS5nZW5vJFNpdGUsIFRvbF9DaGxfTTFfbG0uZ2VubyRncm91cDIsIHNlcD0iXyIpDQoNCiNTaXRlcyB3aXRoaW4gR2Vub3R5cGVzDQpUb2xfQ2hsX00xX2xtLnNpdGU8LWRhdGEuZnJhbWUoZW1tZWFucyhUb2xfQ2hsX00xX2xtLCBwYWlyd2lzZX5TaXRlIHwgR2Vub3R5cGUpJGNvbnRyYXN0cykNClRvbF9DaGxfTTFfbG0uc2l0ZTwtVG9sX0NobF9NMV9sbS5zaXRlICU+JSBzZXBhcmF0ZShjb2w9Y29udHJhc3QsIGludG89YygiZ3JvdXAxIiwgImdyb3VwMiIpLCBzZXA9IiAtICIsIHJlbW92ZT1UUlVFKQ0KVG9sX0NobF9NMV9sbS5zaXRlJGdyb3VwMTwtcGFzdGUoVG9sX0NobF9NMV9sbS5zaXRlJGdyb3VwMSwgVG9sX0NobF9NMV9sbS5zaXRlJEdlbm90eXBlLCBzZXA9Il8iKQ0KVG9sX0NobF9NMV9sbS5zaXRlJGdyb3VwMjwtcGFzdGUoVG9sX0NobF9NMV9sbS5zaXRlJGdyb3VwMiwgVG9sX0NobF9NMV9sbS5zaXRlJEdlbm90eXBlLCBzZXA9Il8iKQ0KDQojRnVsbCBsaXN0IG9mIHAtdmFsdWVzDQpUb2xfQ2hsX00xX2xtLnA8LXJiaW5kKFRvbF9DaGxfTTFfbG0uZ2Vub1ssYygxOjIsNDo4KV0sIFRvbF9DaGxfTTFfbG0uc2l0ZVssYygxOjIsNDo4KV0pDQpUb2xfQ2hsX00xX2xtLnA8LVRvbF9DaGxfTTFfbG0ucCAlPiUgZHBseXI6OnJlbmFtZSggcCA9IHAudmFsdWUpDQoNCiNBZGQgU2lnbmlmaWNhbmNlIExldmVscw0KVG9sX0NobF9NMV9sbS5wJFNpZzwtaWZlbHNlKFRvbF9DaGxfTTFfbG0ucCRwPDAuMDAxLCAiKioqIiwgaWZlbHNlKFRvbF9DaGxfTTFfbG0ucCRwPDAuMDEsICIqKiIsIGlmZWxzZShUb2xfQ2hsX00xX2xtLnAkcDwwLjA1LCAiKiIsIE5BKSkpDQoNCiNTcGVjaWZ5IFJlc3BvbnNlIGFuZCBUaW1lcG9pbnQNClRvbF9DaGxfTTFfbG0ucCRSZXNwb25zZTwtcmVwKCJDaGxvcm9waHlsbCIsIG5yb3coVG9sX0NobF9NMV9sbS5wKSkNClRvbF9DaGxfTTFfbG0ucCRUaW1lUDwtcmVwKCJNMSIsIG5yb3coVG9sX0NobF9NMV9sbS5wKSkNCg0KYGBgDQoNCg0KIyMjIFBsb3QgUmV0ZW50aW9uIGJ5IFNpdGUgYW5kIEdlbm90eXBlDQpgYGB7cn0NCiMjU3VtbWFyeSBzdGF0aXN0aWNzIGJ5IFNpdGUgYW5kIEdlbm90eXBlDQpUb2xfQ2hsX00xX1NHPC1zdW1tYXJ5U0UoVG9sRGF0YV9NMSwgbWVhc3VyZXZhcj0iQ2hsLnByb3AiLCBncm91cHZhcnM9YygiU2l0ZS5HZW5vIiwgIlNpdGUiLCAiR2Vub3R5cGUiKSwgbmEucm09VFJVRSkNCg0KIyNQbG90IEF2ZXJhZ2UgUmV0ZW50aW9uIGFjcm9zcyBUcmVhdG1lbnRzDQpUb2xfQ2hsX00xX1NHLnBsb3Q8LWdncGxvdChUb2xfQ2hsX00xX1NHLCBhZXMoeD1TaXRlLkdlbm8sIHk9Q2hsLnByb3AsIGNvbG91cj1HZW5vdHlwZSkpICsgDQogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49Q2hsLnByb3Atc2UsIHltYXg9Q2hsLnByb3Arc2UpLCB3aWR0aD1jYXAuc3osIGxpbmV3aWR0aD1iYXIuc3opKw0KICBnZW9tX3BvaW50KHNpemU9cG9pbnQuc3opKyANCiAgIGdndGl0bGUoIkNobG9yb3BoeWxsIFJldGVudGlvbiIpKw0KICB0aGVtZV9jbGFzc2ljKCkrDQogIHRoZW1lKCBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IGF4aXMudGl0bGUuc3opLCANCiAgICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIA0KICAgICAgICBheGlzLnRleHQueD1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLA0KICAgICAgICBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLCANCiAgICAgICAgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnR4dC5zeiksDQogICAgICAgIGxlZ2VuZC50aXRsZT1lbGVtZW50X3RleHQoc2l6ZT1sZWcudGl0bGUuc3opLCANCiAgICAgICAgbGVnZW5kLmJveC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGNvbG9yID0gImJsYWNrIiksDQogICAgICAgIGxlZ2VuZC5wb3NpdGlvbj0iYm90dG9tIiwgDQogICAgICAgIGxlZ2VuZC5kaXJlY3Rpb249Imhvcml6b250YWwiLA0KICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSBwbG90LnRpdGxlLnN6LCBjb2xvdXI9ImJsYWNrIiwgaGp1c3QgPSAwLjUpKSsNCiAgbGFicyh4PSIiLCB5PSJQcm9wb3J0aW9uIFJldGFpbmVkIikrDQogIHlsaW0oMCwgMSkrIA0KICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscz1jKCIiLCJLbGVpbiIsIiIsIiIsIlNvbWV0aGluZyBTcGVjaWFsIiwiIikpKw0KICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gR2Vuby5jb2xvcnMubykrIA0KICBzdGF0X3B2YWx1ZV9tYW51YWwoZGF0YT1Ub2xfQ2hsX00xX2xtLnAsICB5LnBvc2l0aW9uPTAuNCwgc3RlcC5pbmNyZWFzZT0wLjI1LCBsYWJlbD0iU2lnIiwgaGlkZS5ucz1UUlVFKTsgVG9sX0NobF9NMV9TRy5wbG90DQoNCmBgYA0KDQoNCiMjIENobCBXaW50ZXIgVGltZXBvaW50IE00DQoNCiMjIyBSdW4gTW9kZWwNCmBgYHtyfQ0KIyNDaGVjayBub3JtYWxpdHkNCmhpc3QoVG9sRGF0YV9NNCRDaGwucHJvcCkNCnNoYXBpcm8udGVzdChUb2xEYXRhX000JENobC5wcm9wKQ0KI05vdCBOb3JtYWwNCg0KIyNUcnkgbG9nKzEgdHJhbnNmb3JtYXRpb24NCmhpc3QobG9nKFRvbERhdGFfTTQkQ2hsLnByb3ArMSkpDQpzaGFwaXJvLnRlc3QobG9nKFRvbERhdGFfTTQkQ2hsLnByb3ArMSkpDQojTm9ybWFsDQoNCiMjTW9kZWwgYXMgYSBmdW5jdGlvbiBvZiBTaXRlIGFuZCBHZW5vdHlwZQ0KIyNNb2RlbCB3aXRoIGxvZyB0cmFuc2Zvcm1hdGlvbg0KVG9sX0NobF9NNF9sbTwtbG0obG9nKENobC5wcm9wKzEpflNpdGUrR2Vub3R5cGUrU2l0ZTpHZW5vdHlwZSwgZGF0YT1Ub2xEYXRhX000KQ0KDQpgYGANCg0KDQojIyMjIENoZWNrIFJlc2lkdWFscw0KYGBge3J9DQojI0NoZWNrIE5vcm1hbGl0eSBvZiBSZXNpZHVhbHMNCiNEaXN0cmlidXRpb24gDQpwbG90KGRlbnNpdHkocmVzaWQoVG9sX0NobF9NNF9sbSkpKQ0KDQojUS1RIHBsb3QNCnFxbm9ybShyZXNpZChUb2xfQ2hsX000X2xtKSk7IHFxbGluZShyZXNpZChUb2xfQ2hsX000X2xtKSkNCg0KIyNDaGVjayBWYXJpYW5jZSBvZiBSZXNpZHVhbHMgYWNyb3NzIEZpdHRlZCBWYWx1ZXMNCnBsb3QoZml0dGVkKFRvbF9DaGxfTTRfbG0pLCByZXNpZChUb2xfQ2hsX000X2xtKSkNCg0KYGBgDQoNCg0KIyMjIE1vZGVsIFJlc3VsdHMNCg0KIyMjIyBPdmVyYWxsDQpgYGB7cn0NCiNNb2RlbCBSZXN1bHRzDQpzdW1tYXJ5KFRvbF9DaGxfTTRfbG0pDQphbm92YShUb2xfQ2hsX000X2xtKQ0KDQojRWZmZWN0IFNpemUgb2YgUHJlZGljdG9ycw0KZXRhX3NxdWFyZWQoVG9sX0NobF9NNF9sbSwgcGFydGlhbD1GQUxTRSkNCg0KIyNTYXZlIG1vZGVsIHJlc3VsdHMNClRvbF9DaGxfTTRfbG0ucmVzPC1kYXRhLmZyYW1lKGFub3ZhKFRvbF9DaGxfTTRfbG0pKQ0KVG9sX0NobF9NNF9sbS5yZXMkUHJlZGljdG9yPC1yb3duYW1lcyhUb2xfQ2hsX000X2xtLnJlcykNClRvbF9DaGxfTTRfbG0ucmVzJEV0YVNxPC1jKGV0YV9zcXVhcmVkKFRvbF9DaGxfTTRfbG0sIHBhcnRpYWw9RkFMU0UpJEV0YTIsIE5BKQ0KVG9sX0NobF9NNF9sbS5yZXMkUmVzcG9uc2U8LXJlcCgiQ2hsb3JvcGh5bGwiLCBucm93KFRvbF9DaGxfTTRfbG0ucmVzKSkNClRvbF9DaGxfTTRfbG0ucmVzJFRpbWVQPC1yZXAoIk00IiwgbnJvdyhUb2xfQ2hsX000X2xtLnJlcykpDQpUb2xfQ2hsX000X2xtLnJlczwtVG9sX0NobF9NNF9sbS5yZXMgJT4lIGRwbHlyOjpyZW5hbWUoIHAudmFsdWUgPSAiUHIuLkYuIiwgREY9ICJEZiIpDQoNCmBgYA0KDQpTaWduaWZpY2FudCBlZmZlY3Qgb2YgU2l0ZSBhbmQgR2Vub3R5cGUgYW5kIFNpdGUqR2Vub3R5cGUuDQoNCg0KIyMjIyBQYWlyd2lzZQ0KYGBge3J9DQojUGFpcndpc2UgY29tcGFyaXNvbnMgYWNyb3NzOg0KDQojR2Vub3R5cGVzIHdpdGhpbiBTaXRlcw0KZW1tZWFucyhUb2xfQ2hsX000X2xtLCBwYWlyd2lzZX5HZW5vdHlwZSB8IFNpdGUpDQoNCiNTaXRlcyB3aXRoaW4gR2Vub3R5cGVzDQplbW1lYW5zKFRvbF9DaGxfTTRfbG0sIHBhaXJ3aXNlflNpdGUgfCBHZW5vdHlwZSkNCg0KIyNTYXZlIHAtdmFsdWVzDQoNCiNHZW5vdHlwZXMgd2l0aGluIFNpdGVzDQpUb2xfQ2hsX000X2xtLmdlbm88LWRhdGEuZnJhbWUoZW1tZWFucyhUb2xfQ2hsX000X2xtLCBwYWlyd2lzZX5HZW5vdHlwZSB8IFNpdGUpJGNvbnRyYXN0cykNClRvbF9DaGxfTTRfbG0uZ2VubzwtVG9sX0NobF9NNF9sbS5nZW5vICU+JSBzZXBhcmF0ZShjb2w9Y29udHJhc3QsIGludG89YygiZ3JvdXAxIiwgImdyb3VwMiIpLCBzZXA9IiAtICIsIHJlbW92ZT1UUlVFKQ0KVG9sX0NobF9NNF9sbS5nZW5vJGdyb3VwMTwtcGFzdGUoVG9sX0NobF9NNF9sbS5nZW5vJFNpdGUsIFRvbF9DaGxfTTRfbG0uZ2VubyRncm91cDEsIHNlcD0iXyIpDQpUb2xfQ2hsX000X2xtLmdlbm8kZ3JvdXAyPC1wYXN0ZShUb2xfQ2hsX000X2xtLmdlbm8kU2l0ZSwgVG9sX0NobF9NNF9sbS5nZW5vJGdyb3VwMiwgc2VwPSJfIikNCg0KI1NpdGVzIHdpdGhpbiBHZW5vdHlwZXMNClRvbF9DaGxfTTRfbG0uc2l0ZTwtZGF0YS5mcmFtZShlbW1lYW5zKFRvbF9DaGxfTTRfbG0sIHBhaXJ3aXNlflNpdGUgfCBHZW5vdHlwZSkkY29udHJhc3RzKQ0KVG9sX0NobF9NNF9sbS5zaXRlPC1Ub2xfQ2hsX000X2xtLnNpdGUgJT4lIHNlcGFyYXRlKGNvbD1jb250cmFzdCwgaW50bz1jKCJncm91cDEiLCAiZ3JvdXAyIiksIHNlcD0iIC0gIiwgcmVtb3ZlPVRSVUUpDQpUb2xfQ2hsX000X2xtLnNpdGUkZ3JvdXAxPC1wYXN0ZShUb2xfQ2hsX000X2xtLnNpdGUkZ3JvdXAxLCBUb2xfQ2hsX000X2xtLnNpdGUkR2Vub3R5cGUsIHNlcD0iXyIpDQpUb2xfQ2hsX000X2xtLnNpdGUkZ3JvdXAyPC1wYXN0ZShUb2xfQ2hsX000X2xtLnNpdGUkZ3JvdXAyLCBUb2xfQ2hsX000X2xtLnNpdGUkR2Vub3R5cGUsIHNlcD0iXyIpDQoNCiNGdWxsIGxpc3Qgb2YgcC12YWx1ZXMNClRvbF9DaGxfTTRfbG0ucDwtcmJpbmQoVG9sX0NobF9NNF9sbS5nZW5vWyxjKDE6Miw0OjgpXSwgVG9sX0NobF9NNF9sbS5zaXRlWyxjKDE6Miw0OjgpXSkNClRvbF9DaGxfTTRfbG0ucDwtVG9sX0NobF9NNF9sbS5wICU+JSBkcGx5cjo6cmVuYW1lKCBwID0gcC52YWx1ZSkNCg0KI0FkZCBTaWduaWZpY2FuY2UgTGV2ZWxzDQpUb2xfQ2hsX000X2xtLnAkU2lnPC1pZmVsc2UoVG9sX0NobF9NNF9sbS5wJHA8MC4wMDEsICIqKioiLCBpZmVsc2UoVG9sX0NobF9NNF9sbS5wJHA8MC4wMSwgIioqIiwgaWZlbHNlKFRvbF9DaGxfTTRfbG0ucCRwPDAuMDUsICIqIiwgTkEpKSkNCg0KI1NwZWNpZnkgUmVzcG9uc2UgYW5kIFRpbWVwb2ludA0KVG9sX0NobF9NNF9sbS5wJFJlc3BvbnNlPC1yZXAoIkNobG9yb3BoeWxsIiwgbnJvdyhUb2xfQ2hsX000X2xtLnApKQ0KVG9sX0NobF9NNF9sbS5wJFRpbWVQPC1yZXAoIk00IiwgbnJvdyhUb2xfQ2hsX000X2xtLnApKQ0KDQpgYGANCg0KDQojIyMgUGxvdCBSZXRlbnRpb24gYnkgU2l0ZSBhbmQgR2Vub3R5cGUNCmBgYHtyfQ0KIyNTdW1tYXJ5IHN0YXRpc3RpY3MgYnkgU2l0ZSBhbmQgR2Vub3R5cGUNClRvbF9DaGxfTTRfU0c8LXN1bW1hcnlTRShUb2xEYXRhX000LCBtZWFzdXJldmFyPSJDaGwucHJvcCIsIGdyb3VwdmFycz1jKCJTaXRlLkdlbm8iLCAiU2l0ZSIsICJHZW5vdHlwZSIpLCBuYS5ybT1UUlVFKQ0KDQojI1Bsb3QgQXZlcmFnZSBSZXRlbnRpb24gYWNyb3NzIFRyZWF0bWVudHMNClRvbF9DaGxfTTRfU0cucGxvdDwtZ2dwbG90KFRvbF9DaGxfTTRfU0csIGFlcyh4PVNpdGUuR2VubywgeT1DaGwucHJvcCwgY29sb3VyPUdlbm90eXBlKSkgKyANCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1DaGwucHJvcC1zZSwgeW1heD1DaGwucHJvcCtzZSksIHdpZHRoPWNhcC5zeiwgbGluZXdpZHRoPWJhci5zeikrDQogIGdlb21fcG9pbnQoc2l6ZT1wb2ludC5zeikrIA0KICAgZ2d0aXRsZSgiQ2hsb3JvcGh5bGwgUmV0ZW50aW9uIikrDQogIHRoZW1lX2NsYXNzaWMoKSsNCiAgdGhlbWUoIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIA0KICAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSBheGlzLnRpdGxlLnN6KSwgDQogICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksDQogICAgICAgIGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksIA0KICAgICAgICBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoc2l6ZT1sZWcudHh0LnN6KSwNCiAgICAgICAgbGVnZW5kLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPWxlZy50aXRsZS5zeiksIA0KICAgICAgICBsZWdlbmQuYm94LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoY29sb3IgPSAiYmxhY2siKSwNCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJib3R0b20iLCANCiAgICAgICAgbGVnZW5kLmRpcmVjdGlvbj0iaG9yaXpvbnRhbCIsDQogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHBsb3QudGl0bGUuc3osIGNvbG91cj0iYmxhY2siLCBoanVzdCA9IDAuNSkpKw0KICBsYWJzKHg9IiIsIHk9IlByb3BvcnRpb24gUmV0YWluZWQiKSsNCiAgeWxpbSgwLCAxKSsgDQogIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzPWMoIiIsIktsZWluIiwiIiwiIiwiU29tZXRoaW5nIFNwZWNpYWwiLCIiKSkrDQogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBHZW5vLmNvbG9ycy5vKSsgDQogIHN0YXRfcHZhbHVlX21hbnVhbChkYXRhPVRvbF9DaGxfTTRfbG0ucCwgIHkucG9zaXRpb249MC41NSwgc3RlcC5pbmNyZWFzZT0wLjIwLCBsYWJlbD0iU2lnIiwgaGlkZS5ucz1UUlVFKTsgVG9sX0NobF9NNF9TRy5wbG90DQoNCmBgYA0KDQoNCiMgVGhlcm1hbCBUb2xlcmFuY2UgU3ltYmlvbnRzDQoNCiMjIEZ1bGwgU2V0DQoNCiMjIyBSdW4gTW9kZWwNCmBgYHtyfQ0KIyNDaGVjayBub3JtYWxpdHkNCmhpc3QoVG9sRGF0YSRTeW0ucHJvcCkNCnNoYXBpcm8udGVzdChUb2xEYXRhJFN5bS5wcm9wKQ0KI05vdCBOb3JtYWwNCg0KIyNUcnkgbG9nKzEgdHJhbnNmb3JtYXRpb24NCmhpc3QobG9nKFRvbERhdGEkU3ltLnByb3ArMSkpDQpzaGFwaXJvLnRlc3QobG9nKFRvbERhdGEkU3ltLnByb3ArMSkpDQojTm90IG5vcm1hbCANCg0KIyNUcnkgc3F1YXJlIHRyYW5zZm9ybWF0aW9uDQpoaXN0KChUb2xEYXRhJFN5bS5wcm9wKV4yKQ0Kc2hhcGlyby50ZXN0KChUb2xEYXRhJFN5bS5wcm9wKV4yKQ0KI05vdCBub3JtYWwgDQoNCiMjVHJ5IGN1YmVkIHRyYW5zZm9ybWF0aW9uDQpoaXN0KChUb2xEYXRhJFN5bS5wcm9wKV4zKQ0Kc2hhcGlyby50ZXN0KChUb2xEYXRhJFN5bS5wcm9wKV4zKQ0KI05vdCBub3JtYWwgDQoNCg0KIyNNb2RlbCBhcyBhIGZ1bmN0aW9uIG9mIFNpdGUgYW5kIEdlbm90eXBlIGFuZCBUaW1lcG9pbnQNCiMjTW9kZWwgd2l0aCBubyB0cmFuc2Zvcm1hdGlvbiBhbmQgY2hlY2sgcmVzaWR1YWxzDQpUb2xfU3ltX2xtPC1sbShTeW0ucHJvcH5TaXRlK0dlbm90eXBlK1RpbWVQKyBTaXRlOkdlbm90eXBlICsgU2l0ZTpUaW1lUCArIEdlbm90eXBlOlRpbWVQLCBkYXRhPVRvbERhdGEpDQoNCmBgYA0KDQoNCiMjIyMgQ2hlY2sgUmVzaWR1YWxzDQpgYGB7cn0NCiMjQ2hlY2sgTm9ybWFsaXR5IG9mIFJlc2lkdWFscw0KI0Rpc3RyaWJ1dGlvbiANCnBsb3QoZGVuc2l0eShyZXNpZChUb2xfU3ltX2xtKSkpDQoNCiNRLVEgcGxvdA0KcXFub3JtKHJlc2lkKFRvbF9TeW1fbG0pKTsgcXFsaW5lKHJlc2lkKFRvbF9TeW1fbG0pKQ0KDQojI0NoZWNrIFZhcmlhbmNlIG9mIFJlc2lkdWFscyBhY3Jvc3MgRml0dGVkIFZhbHVlcw0KcGxvdChmaXR0ZWQoVG9sX1N5bV9sbSksIHJlc2lkKFRvbF9TeW1fbG0pKQ0KDQpgYGANCg0KDQojIyMgTW9kZWwgUmVzdWx0cw0KDQpgYGB7cn0NCiNNb2RlbCBSZXN1bHRzDQpzdW1tYXJ5KFRvbF9TeW1fbG0pDQphbm92YShUb2xfU3ltX2xtKQ0KDQojRWZmZWN0IFNpemUgb2YgUHJlZGljdG9ycw0KZXRhX3NxdWFyZWQoVG9sX1N5bV9sbSwgcGFydGlhbD1GQUxTRSkNCg0KIyNTYXZlIG1vZGVsIHJlc3VsdHMNClRvbF9TeW1fbG0ucmVzPC1kYXRhLmZyYW1lKGFub3ZhKFRvbF9TeW1fbG0pKQ0KVG9sX1N5bV9sbS5yZXMkUHJlZGljdG9yPC1yb3duYW1lcyhUb2xfU3ltX2xtLnJlcykNClRvbF9TeW1fbG0ucmVzJEV0YVNxPC1jKGV0YV9zcXVhcmVkKFRvbF9TeW1fbG0sIHBhcnRpYWw9RkFMU0UpJEV0YTIsIE5BKQ0KVG9sX1N5bV9sbS5yZXMkUmVzcG9uc2U8LXJlcCgiU3ltYmlvbnRzIiwgbnJvdyhUb2xfU3ltX2xtLnJlcykpDQpUb2xfU3ltX2xtLnJlczwtVG9sX1N5bV9sbS5yZXMgJT4lIGRwbHlyOjpyZW5hbWUoIHAudmFsdWUgPSAiUHIuLkYuIiwgREY9ICJEZiIpDQoNCmBgYA0KU3Ryb25nIGluZmx1ZW5jZSBvZiBUaW1lcG9pbnQsIGluY2x1ZGluZyBpbnRlcmFjdGlvbnMgd2l0aCBtYWluIHZhcmlhYmxlcyBvZiBpbnRlcmVzdCwgU2l0ZSBhbmQgR2Vub3R5cGUuIFdpbGwgYW5hbHl6ZSBlYWNoIFRpbWVwb2ludCBpbmRpdmlkdWFsbHkuIA0KDQoNCiMjIFN5bSBTdW1tZXIgMSBUaW1lcG9pbnQgVzINCg0KIyMjIFJ1biBNb2RlbA0KYGBge3J9DQojI0NoZWNrIG5vcm1hbGl0eQ0KaGlzdChUb2xEYXRhX1cyJFN5bS5wcm9wKQ0Kc2hhcGlyby50ZXN0KFRvbERhdGFfVzIkU3ltLnByb3ApDQojTm9ybWFsDQoNCiMjTW9kZWwgYXMgYSBmdW5jdGlvbiBvZiBTaXRlIGFuZCBHZW5vdHlwZQ0KVG9sX1N5bV9XMl9sbTwtbG0oU3ltLnByb3B+U2l0ZStHZW5vdHlwZStTaXRlOkdlbm90eXBlLCBkYXRhPVRvbERhdGFfVzIpDQoNCmBgYA0KDQoNCiMjIyMgQ2hlY2sgUmVzaWR1YWxzDQpgYGB7cn0NCiMjQ2hlY2sgTm9ybWFsaXR5IG9mIFJlc2lkdWFscw0KI0Rpc3RyaWJ1dGlvbiANCnBsb3QoZGVuc2l0eShyZXNpZChUb2xfU3ltX1cyX2xtKSkpDQoNCiNRLVEgcGxvdA0KcXFub3JtKHJlc2lkKFRvbF9TeW1fVzJfbG0pKTsgcXFsaW5lKHJlc2lkKFRvbF9TeW1fVzJfbG0pKQ0KDQojI0NoZWNrIFZhcmlhbmNlIG9mIFJlc2lkdWFscyBhY3Jvc3MgRml0dGVkIFZhbHVlcw0KcGxvdChmaXR0ZWQoVG9sX1N5bV9XMl9sbSksIHJlc2lkKFRvbF9TeW1fVzJfbG0pKQ0KDQpgYGANCg0KDQojIyMgTW9kZWwgUmVzdWx0cw0KDQojIyMjIE92ZXJhbGwNCmBgYHtyfQ0KI01vZGVsIFJlc3VsdHMNCnN1bW1hcnkoVG9sX1N5bV9XMl9sbSkNCmFub3ZhKFRvbF9TeW1fVzJfbG0pDQoNCiNFZmZlY3QgU2l6ZSBvZiBQcmVkaWN0b3JzDQpldGFfc3F1YXJlZChUb2xfU3ltX1cyX2xtLCBwYXJ0aWFsPUZBTFNFKQ0KDQojI1NhdmUgbW9kZWwgcmVzdWx0cw0KVG9sX1N5bV9XMl9sbS5yZXM8LWRhdGEuZnJhbWUoYW5vdmEoVG9sX1N5bV9XMl9sbSkpDQpUb2xfU3ltX1cyX2xtLnJlcyRQcmVkaWN0b3I8LXJvd25hbWVzKFRvbF9TeW1fVzJfbG0ucmVzKQ0KVG9sX1N5bV9XMl9sbS5yZXMkRXRhU3E8LWMoZXRhX3NxdWFyZWQoVG9sX1N5bV9XMl9sbSwgcGFydGlhbD1GQUxTRSkkRXRhMiwgTkEpDQpUb2xfU3ltX1cyX2xtLnJlcyRSZXNwb25zZTwtcmVwKCJTeW1iaW9udHMiLCBucm93KFRvbF9TeW1fVzJfbG0ucmVzKSkNClRvbF9TeW1fVzJfbG0ucmVzJFRpbWVQPC1yZXAoIlcyIiwgbnJvdyhUb2xfU3ltX1cyX2xtLnJlcykpDQpUb2xfU3ltX1cyX2xtLnJlczwtVG9sX1N5bV9XMl9sbS5yZXMgJT4lIGRwbHlyOjpyZW5hbWUoIHAudmFsdWUgPSAiUHIuLkYuIiwgREY9ICJEZiIpDQoNCmBgYA0KDQpTaWduaWZpY2FudCBlZmZlY3Qgb2YgU2l0ZSBhbmQgR2Vub3R5cGUuIE1hcmdpbmFsIGVmZmVjdCAocDwwLjEpIG9mIFNpdGUgKiBHZW5vdHlwZS4gU3RpbGwgY2hlY2tpbmcgU2l0ZSpHZW5vdHlwZSBmb3IgY29tcGFyYWJpbGl0eSBhY3Jvc3MgVGltZXBvaW50cy4NCg0KDQoNCiMjIyMgUGFpcndpc2UNCmBgYHtyfQ0KI1BhaXJ3aXNlIGNvbXBhcmlzb25zIGFjcm9zczoNCg0KI0dlbm90eXBlcyB3aXRoaW4gU2l0ZXMNCmVtbWVhbnMoVG9sX1N5bV9XMl9sbSwgcGFpcndpc2V+R2Vub3R5cGUgfCBTaXRlKQ0KDQojU2l0ZXMgd2l0aGluIEdlbm90eXBlcw0KZW1tZWFucyhUb2xfU3ltX1cyX2xtLCBwYWlyd2lzZX5TaXRlIHwgR2Vub3R5cGUpDQoNCiMjU2F2ZSBwLXZhbHVlcw0KDQojR2Vub3R5cGVzIHdpdGhpbiBTaXRlcw0KVG9sX1N5bV9XMl9sbS5nZW5vPC1kYXRhLmZyYW1lKGVtbWVhbnMoVG9sX1N5bV9XMl9sbSwgcGFpcndpc2V+R2Vub3R5cGUgfCBTaXRlKSRjb250cmFzdHMpDQpUb2xfU3ltX1cyX2xtLmdlbm88LVRvbF9TeW1fVzJfbG0uZ2VubyAlPiUgc2VwYXJhdGUoY29sPWNvbnRyYXN0LCBpbnRvPWMoImdyb3VwMSIsICJncm91cDIiKSwgc2VwPSIgLSAiLCByZW1vdmU9VFJVRSkNClRvbF9TeW1fVzJfbG0uZ2VubyRncm91cDE8LXBhc3RlKFRvbF9TeW1fVzJfbG0uZ2VubyRTaXRlLCBUb2xfU3ltX1cyX2xtLmdlbm8kZ3JvdXAxLCBzZXA9Il8iKQ0KVG9sX1N5bV9XMl9sbS5nZW5vJGdyb3VwMjwtcGFzdGUoVG9sX1N5bV9XMl9sbS5nZW5vJFNpdGUsIFRvbF9TeW1fVzJfbG0uZ2VubyRncm91cDIsIHNlcD0iXyIpDQoNCiNTaXRlcyB3aXRoaW4gR2Vub3R5cGVzDQpUb2xfU3ltX1cyX2xtLnNpdGU8LWRhdGEuZnJhbWUoZW1tZWFucyhUb2xfU3ltX1cyX2xtLCBwYWlyd2lzZX5TaXRlIHwgR2Vub3R5cGUpJGNvbnRyYXN0cykNClRvbF9TeW1fVzJfbG0uc2l0ZTwtVG9sX1N5bV9XMl9sbS5zaXRlICU+JSBzZXBhcmF0ZShjb2w9Y29udHJhc3QsIGludG89YygiZ3JvdXAxIiwgImdyb3VwMiIpLCBzZXA9IiAtICIsIHJlbW92ZT1UUlVFKQ0KVG9sX1N5bV9XMl9sbS5zaXRlJGdyb3VwMTwtcGFzdGUoVG9sX1N5bV9XMl9sbS5zaXRlJGdyb3VwMSwgVG9sX1N5bV9XMl9sbS5zaXRlJEdlbm90eXBlLCBzZXA9Il8iKQ0KVG9sX1N5bV9XMl9sbS5zaXRlJGdyb3VwMjwtcGFzdGUoVG9sX1N5bV9XMl9sbS5zaXRlJGdyb3VwMiwgVG9sX1N5bV9XMl9sbS5zaXRlJEdlbm90eXBlLCBzZXA9Il8iKQ0KDQojRnVsbCBsaXN0IG9mIHAtdmFsdWVzDQpUb2xfU3ltX1cyX2xtLnA8LXJiaW5kKFRvbF9TeW1fVzJfbG0uZ2Vub1ssYygxOjIsNDo4KV0sIFRvbF9TeW1fVzJfbG0uc2l0ZVssYygxOjIsNDo4KV0pDQpUb2xfU3ltX1cyX2xtLnA8LVRvbF9TeW1fVzJfbG0ucCAlPiUgZHBseXI6OnJlbmFtZSggcCA9IHAudmFsdWUpDQoNCiNBZGQgU2lnbmlmaWNhbmNlIExldmVscw0KVG9sX1N5bV9XMl9sbS5wJFNpZzwtaWZlbHNlKFRvbF9TeW1fVzJfbG0ucCRwPDAuMDAxLCAiKioqIiwgaWZlbHNlKFRvbF9TeW1fVzJfbG0ucCRwPDAuMDEsICIqKiIsIGlmZWxzZShUb2xfU3ltX1cyX2xtLnAkcDwwLjA1LCAiKiIsIE5BKSkpDQoNCiNTcGVjaWZ5IFJlc3BvbnNlIGFuZCBUaW1lcG9pbnQNClRvbF9TeW1fVzJfbG0ucCRSZXNwb25zZTwtcmVwKCJTeW1iaW9udHMiLCBucm93KFRvbF9TeW1fVzJfbG0ucCkpDQpUb2xfU3ltX1cyX2xtLnAkVGltZVA8LXJlcCgiVzIiLCBucm93KFRvbF9TeW1fVzJfbG0ucCkpDQoNCmBgYA0KDQoNCiMjIyBQbG90IFJldGVudGlvbiBieSBTaXRlIGFuZCBHZW5vdHlwZQ0KYGBge3J9DQojI1N1bW1hcnkgc3RhdGlzdGljcyBieSBTaXRlIGFuZCBHZW5vdHlwZQ0KVG9sX1N5bV9XMl9TRzwtc3VtbWFyeVNFKFRvbERhdGFfVzIsIG1lYXN1cmV2YXI9IlN5bS5wcm9wIiwgZ3JvdXB2YXJzPWMoIlNpdGUuR2VubyIsICJTaXRlIiwgIkdlbm90eXBlIiksIG5hLnJtPVRSVUUpDQoNCiMjUGxvdCBBdmVyYWdlIFJldGVudGlvbiBhY3Jvc3MgVHJlYXRtZW50cw0KVG9sX1N5bV9XMl9TRy5wbG90PC1nZ3Bsb3QoVG9sX1N5bV9XMl9TRywgYWVzKHg9U2l0ZS5HZW5vLCB5PVN5bS5wcm9wLCBjb2xvdXI9R2Vub3R5cGUpKSArIA0KICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluPVN5bS5wcm9wLXNlLCB5bWF4PVN5bS5wcm9wK3NlKSwgd2lkdGg9Y2FwLnN6LCBsaW5ld2lkdGg9YmFyLnN6KSsNCiAgZ2VvbV9wb2ludChzaXplPXBvaW50LnN6KSsgDQogICBnZ3RpdGxlKCJTeW1iaW9udCBSZXRlbnRpb24iKSsNCiAgdGhlbWVfY2xhc3NpYygpKw0KICB0aGVtZSggYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSBheGlzLnRpdGxlLnN6KSwgDQogICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IGF4aXMudGl0bGUuc3opLCANCiAgICAgICAgYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50eHQuc3osIGNvbG91cj0iYmxhY2siKSwNCiAgICAgICAgYXhpcy50ZXh0Lnk9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50eHQuc3osIGNvbG91cj0iYmxhY2siKSwgDQogICAgICAgIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPWxlZy50eHQuc3opLA0KICAgICAgICBsZWdlbmQudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnRpdGxlLnN6KSwgDQogICAgICAgIGxlZ2VuZC5ib3guYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChjb2xvciA9ICJibGFjayIpLA0KICAgICAgICBsZWdlbmQucG9zaXRpb249ImJvdHRvbSIsIA0KICAgICAgICBsZWdlbmQuZGlyZWN0aW9uPSJob3Jpem9udGFsIiwNCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gcGxvdC50aXRsZS5zeiwgY29sb3VyPSJibGFjayIsIGhqdXN0ID0gMC41KSkrDQogIGxhYnMoeD0iIiwgeT0iUHJvcG9ydGlvbiBSZXRhaW5lZCIpKw0KICB5bGltKDAsIDEuNSkrIA0KICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscz1jKCIiLCJLbGVpbiIsIiIsIiIsIlNvbWV0aGluZyBTcGVjaWFsIiwiIikpKw0KICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gR2Vuby5jb2xvcnMubykrIA0KICBzdGF0X3B2YWx1ZV9tYW51YWwoZGF0YT1Ub2xfU3ltX1cyX2xtLnAsICB5LnBvc2l0aW9uPTAuOTUsIHN0ZXAuaW5jcmVhc2U9MC4xNSwgbGFiZWw9IlNpZyIsIGhpZGUubnM9VFJVRSk7IFRvbF9TeW1fVzJfU0cucGxvdA0KDQpgYGANCg0KDQojIyBTeW0gU3VtbWVyIDIgVGltZXBvaW50IE0xDQoNCiMjIyBSdW4gTW9kZWwNCmBgYHtyfQ0KIyNDaGVjayBub3JtYWxpdHkNCmhpc3QoVG9sRGF0YV9NMSRTeW0ucHJvcCkNCnNoYXBpcm8udGVzdChUb2xEYXRhX00xJFN5bS5wcm9wKQ0KI05vdCBub3JtYWwNCg0KIyNUcnkgbG9nKzEgdHJhbnNmb3JtYXRpb24NCmhpc3QobG9nKFRvbERhdGFfTTEkU3ltLnByb3ArMSkpDQpzaGFwaXJvLnRlc3QobG9nKFRvbERhdGFfTTEkU3ltLnByb3ArMSkpDQojTm90IG5vcm1hbCBidXQgaW1wcm92ZWQNCg0KIyNNb2RlbCBhcyBhIGZ1bmN0aW9uIG9mIFNpdGUgYW5kIEdlbm90eXBlDQojI01vZGVsIHdpdGggbG9nIHRyYW5zZm9ybWF0aW9uDQpUb2xfU3ltX00xX2xtPC1sbShsb2coU3ltLnByb3ArMSl+U2l0ZStHZW5vdHlwZStTaXRlOkdlbm90eXBlLCBkYXRhPVRvbERhdGFfTTEpDQoNCmBgYA0KDQoNCiMjIyMgQ2hlY2sgUmVzaWR1YWxzDQpgYGB7cn0NCiMjQ2hlY2sgTm9ybWFsaXR5IG9mIFJlc2lkdWFscw0KI0Rpc3RyaWJ1dGlvbiANCnBsb3QoZGVuc2l0eShyZXNpZChUb2xfU3ltX00xX2xtKSkpDQoNCiNRLVEgcGxvdA0KcXFub3JtKHJlc2lkKFRvbF9TeW1fTTFfbG0pKTsgcXFsaW5lKHJlc2lkKFRvbF9TeW1fTTFfbG0pKQ0KDQojI0NoZWNrIFZhcmlhbmNlIG9mIFJlc2lkdWFscyBhY3Jvc3MgRml0dGVkIFZhbHVlcw0KcGxvdChmaXR0ZWQoVG9sX1N5bV9NMV9sbSksIHJlc2lkKFRvbF9TeW1fTTFfbG0pKQ0KDQpgYGANCg0KDQojIyMgTW9kZWwgUmVzdWx0cw0KDQojIyMjIE92ZXJhbGwNCmBgYHtyfQ0KI01vZGVsIFJlc3VsdHMNCnN1bW1hcnkoVG9sX1N5bV9NMV9sbSkNCmFub3ZhKFRvbF9TeW1fTTFfbG0pDQoNCiNFZmZlY3QgU2l6ZSBvZiBQcmVkaWN0b3JzDQpldGFfc3F1YXJlZChUb2xfU3ltX00xX2xtLCBwYXJ0aWFsPUZBTFNFKQ0KDQojI1NhdmUgbW9kZWwgcmVzdWx0cw0KVG9sX1N5bV9NMV9sbS5yZXM8LWRhdGEuZnJhbWUoYW5vdmEoVG9sX1N5bV9NMV9sbSkpDQpUb2xfU3ltX00xX2xtLnJlcyRQcmVkaWN0b3I8LXJvd25hbWVzKFRvbF9TeW1fTTFfbG0ucmVzKQ0KVG9sX1N5bV9NMV9sbS5yZXMkRXRhU3E8LWMoZXRhX3NxdWFyZWQoVG9sX1N5bV9NMV9sbSwgcGFydGlhbD1GQUxTRSkkRXRhMiwgTkEpDQpUb2xfU3ltX00xX2xtLnJlcyRSZXNwb25zZTwtcmVwKCJTeW1iaW9udHMiLCBucm93KFRvbF9TeW1fTTFfbG0ucmVzKSkNClRvbF9TeW1fTTFfbG0ucmVzJFRpbWVQPC1yZXAoIk0xIiwgbnJvdyhUb2xfU3ltX00xX2xtLnJlcykpDQpUb2xfU3ltX00xX2xtLnJlczwtVG9sX1N5bV9NMV9sbS5yZXMgJT4lIGRwbHlyOjpyZW5hbWUoIHAudmFsdWUgPSAiUHIuLkYuIiwgREY9ICJEZiIpDQoNCmBgYA0KDQpTaWduaWZpY2FudCBlZmZlY3Qgb2YgR2Vub3R5cGUuIFN0aWxsIGNoZWNraW5nIFNpdGUqR2Vub3R5cGUgZm9yIGNvbXBhcmFiaWxpdHkgYWNyb3NzIFRpbWVwb2ludHMuDQoNCg0KIyMjIyBQYWlyd2lzZQ0KYGBge3J9DQojUGFpcndpc2UgY29tcGFyaXNvbnMgYWNyb3NzOg0KDQojR2Vub3R5cGVzIHdpdGhpbiBTaXRlcw0KZW1tZWFucyhUb2xfU3ltX00xX2xtLCBwYWlyd2lzZX5HZW5vdHlwZSB8IFNpdGUpDQoNCiNTaXRlcyB3aXRoaW4gR2Vub3R5cGVzDQplbW1lYW5zKFRvbF9TeW1fTTFfbG0sIHBhaXJ3aXNlflNpdGUgfCBHZW5vdHlwZSkNCg0KIyNTYXZlIHAtdmFsdWVzDQoNCiNHZW5vdHlwZXMgd2l0aGluIFNpdGVzDQpUb2xfU3ltX00xX2xtLmdlbm88LWRhdGEuZnJhbWUoZW1tZWFucyhUb2xfU3ltX00xX2xtLCBwYWlyd2lzZX5HZW5vdHlwZSB8IFNpdGUpJGNvbnRyYXN0cykNClRvbF9TeW1fTTFfbG0uZ2VubzwtVG9sX1N5bV9NMV9sbS5nZW5vICU+JSBzZXBhcmF0ZShjb2w9Y29udHJhc3QsIGludG89YygiZ3JvdXAxIiwgImdyb3VwMiIpLCBzZXA9IiAtICIsIHJlbW92ZT1UUlVFKQ0KVG9sX1N5bV9NMV9sbS5nZW5vJGdyb3VwMTwtcGFzdGUoVG9sX1N5bV9NMV9sbS5nZW5vJFNpdGUsIFRvbF9TeW1fTTFfbG0uZ2VubyRncm91cDEsIHNlcD0iXyIpDQpUb2xfU3ltX00xX2xtLmdlbm8kZ3JvdXAyPC1wYXN0ZShUb2xfU3ltX00xX2xtLmdlbm8kU2l0ZSwgVG9sX1N5bV9NMV9sbS5nZW5vJGdyb3VwMiwgc2VwPSJfIikNCg0KI1NpdGVzIHdpdGhpbiBHZW5vdHlwZXMNClRvbF9TeW1fTTFfbG0uc2l0ZTwtZGF0YS5mcmFtZShlbW1lYW5zKFRvbF9TeW1fTTFfbG0sIHBhaXJ3aXNlflNpdGUgfCBHZW5vdHlwZSkkY29udHJhc3RzKQ0KVG9sX1N5bV9NMV9sbS5zaXRlPC1Ub2xfU3ltX00xX2xtLnNpdGUgJT4lIHNlcGFyYXRlKGNvbD1jb250cmFzdCwgaW50bz1jKCJncm91cDEiLCAiZ3JvdXAyIiksIHNlcD0iIC0gIiwgcmVtb3ZlPVRSVUUpDQpUb2xfU3ltX00xX2xtLnNpdGUkZ3JvdXAxPC1wYXN0ZShUb2xfU3ltX00xX2xtLnNpdGUkZ3JvdXAxLCBUb2xfU3ltX00xX2xtLnNpdGUkR2Vub3R5cGUsIHNlcD0iXyIpDQpUb2xfU3ltX00xX2xtLnNpdGUkZ3JvdXAyPC1wYXN0ZShUb2xfU3ltX00xX2xtLnNpdGUkZ3JvdXAyLCBUb2xfU3ltX00xX2xtLnNpdGUkR2Vub3R5cGUsIHNlcD0iXyIpDQoNCiNGdWxsIGxpc3Qgb2YgcC12YWx1ZXMNClRvbF9TeW1fTTFfbG0ucDwtcmJpbmQoVG9sX1N5bV9NMV9sbS5nZW5vWyxjKDE6Miw0OjgpXSwgVG9sX1N5bV9NMV9sbS5zaXRlWyxjKDE6Miw0OjgpXSkNClRvbF9TeW1fTTFfbG0ucDwtVG9sX1N5bV9NMV9sbS5wICU+JSBkcGx5cjo6cmVuYW1lKCBwID0gcC52YWx1ZSkNCg0KI0FkZCBTaWduaWZpY2FuY2UgTGV2ZWxzDQpUb2xfU3ltX00xX2xtLnAkU2lnPC1pZmVsc2UoVG9sX1N5bV9NMV9sbS5wJHA8MC4wMDEsICIqKioiLCBpZmVsc2UoVG9sX1N5bV9NMV9sbS5wJHA8MC4wMSwgIioqIiwgaWZlbHNlKFRvbF9TeW1fTTFfbG0ucCRwPDAuMDUsICIqIiwgTkEpKSkNCg0KI1NwZWNpZnkgUmVzcG9uc2UgYW5kIFRpbWVwb2ludA0KVG9sX1N5bV9NMV9sbS5wJFJlc3BvbnNlPC1yZXAoIlN5bWJpb250cyIsIG5yb3coVG9sX1N5bV9NMV9sbS5wKSkNClRvbF9TeW1fTTFfbG0ucCRUaW1lUDwtcmVwKCJNMSIsIG5yb3coVG9sX1N5bV9NMV9sbS5wKSkNCg0KYGBgDQoNCg0KIyMjIFBsb3QgUmV0ZW50aW9uIGJ5IFNpdGUgYW5kIEdlbm90eXBlDQpgYGB7cn0NCiMjU3VtbWFyeSBzdGF0aXN0aWNzIGJ5IFNpdGUgYW5kIEdlbm90eXBlDQpUb2xfU3ltX00xX1NHPC1zdW1tYXJ5U0UoVG9sRGF0YV9NMSwgbWVhc3VyZXZhcj0iU3ltLnByb3AiLCBncm91cHZhcnM9YygiU2l0ZS5HZW5vIiwgIlNpdGUiLCAiR2Vub3R5cGUiKSwgbmEucm09VFJVRSkNCg0KIyNQbG90IEF2ZXJhZ2UgUmV0ZW50aW9uIGFjcm9zcyBUcmVhdG1lbnRzDQpUb2xfU3ltX00xX1NHLnBsb3Q8LWdncGxvdChUb2xfU3ltX00xX1NHLCBhZXMoeD1TaXRlLkdlbm8sIHk9U3ltLnByb3AsIGNvbG91cj1HZW5vdHlwZSkpICsgDQogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49U3ltLnByb3Atc2UsIHltYXg9U3ltLnByb3Arc2UpLCB3aWR0aD1jYXAuc3osIGxpbmV3aWR0aD1iYXIuc3opKw0KICBnZW9tX3BvaW50KHNpemU9cG9pbnQuc3opKyANCiAgIGdndGl0bGUoIlN5bWJpb250IFJldGVudGlvbiIpKw0KICB0aGVtZV9jbGFzc2ljKCkrDQogIHRoZW1lKCBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IGF4aXMudGl0bGUuc3opLCANCiAgICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIA0KICAgICAgICBheGlzLnRleHQueD1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLA0KICAgICAgICBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLCANCiAgICAgICAgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnR4dC5zeiksDQogICAgICAgIGxlZ2VuZC50aXRsZT1lbGVtZW50X3RleHQoc2l6ZT1sZWcudGl0bGUuc3opLCANCiAgICAgICAgbGVnZW5kLmJveC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGNvbG9yID0gImJsYWNrIiksDQogICAgICAgIGxlZ2VuZC5wb3NpdGlvbj0iYm90dG9tIiwgDQogICAgICAgIGxlZ2VuZC5kaXJlY3Rpb249Imhvcml6b250YWwiLA0KICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSBwbG90LnRpdGxlLnN6LCBjb2xvdXI9ImJsYWNrIiwgaGp1c3QgPSAwLjUpKSsNCiAgbGFicyh4PSIiLCB5PSJQcm9wb3J0aW9uIFJldGFpbmVkIikrDQogeWxpbSgwLCAxLjUpKyANCiAgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHM9YygiIiwiS2xlaW4iLCIiLCIiLCJTb21ldGhpbmcgU3BlY2lhbCIsIiIpKSsNCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IEdlbm8uY29sb3JzLm8pKyANCiAgc3RhdF9wdmFsdWVfbWFudWFsKGRhdGE9VG9sX1N5bV9NMV9sbS5wLCAgeS5wb3NpdGlvbj0wLjk1LCBzdGVwLmluY3JlYXNlPTAuMTUsIGxhYmVsPSJTaWciLCBoaWRlLm5zPVRSVUUpOyBUb2xfU3ltX00xX1NHLnBsb3QNCg0KYGBgDQoNCg0KIyMgU3ltIFdpbnRlciBUaW1lcG9pbnQgTTQNCg0KIyMjIFJ1biBNb2RlbA0KYGBge3J9DQojI0NoZWNrIG5vcm1hbGl0eQ0KaGlzdChUb2xEYXRhX000JFN5bS5wcm9wKQ0Kc2hhcGlyby50ZXN0KFRvbERhdGFfTTQkU3ltLnByb3ApDQojTm90IE5vcm1hbA0KDQojI1RyeSBzcXVhcmUgdHJhbnNmb3JtYXRpb24NCmhpc3QoKFRvbERhdGFfTTQkU3ltLnByb3ApXjIpDQpzaGFwaXJvLnRlc3QoKFRvbERhdGFfTTQkU3ltLnByb3ApXjIpDQojTm90IE5vcm1hbA0KDQojI1RyeSBjdWJlZCB0cmFuc2Zvcm1hdGlvbg0KaGlzdCgoVG9sRGF0YV9NNCRTeW0ucHJvcCleMykNCnNoYXBpcm8udGVzdCgoVG9sRGF0YV9NNCRTeW0ucHJvcCleMykNCiNOb3QgTm9ybWFsDQoNCiMjTW9kZWwgYXMgYSBmdW5jdGlvbiBvZiBTaXRlIGFuZCBHZW5vdHlwZQ0KIyNNb2RlbCB3aXRoIG5vIHRyYW5zZm9ybWF0aW9uIGFuZCBjaGVjayByZXNpZHVhbHMNClRvbF9TeW1fTTRfbG08LWxtKFN5bS5wcm9wflNpdGUrR2Vub3R5cGUrU2l0ZTpHZW5vdHlwZSwgZGF0YT1Ub2xEYXRhX000KQ0KDQpgYGANCg0KDQojIyMjIENoZWNrIFJlc2lkdWFscw0KYGBge3J9DQojI0NoZWNrIE5vcm1hbGl0eSBvZiBSZXNpZHVhbHMNCiNEaXN0cmlidXRpb24gDQpwbG90KGRlbnNpdHkocmVzaWQoVG9sX1N5bV9NNF9sbSkpKQ0KDQojUS1RIHBsb3QNCnFxbm9ybShyZXNpZChUb2xfU3ltX000X2xtKSk7IHFxbGluZShyZXNpZChUb2xfU3ltX000X2xtKSkNCg0KIyNDaGVjayBWYXJpYW5jZSBvZiBSZXNpZHVhbHMgYWNyb3NzIEZpdHRlZCBWYWx1ZXMNCnBsb3QoZml0dGVkKFRvbF9TeW1fTTRfbG0pLCByZXNpZChUb2xfU3ltX000X2xtKSkNCg0KYGBgDQoNCg0KIyMjIE1vZGVsIFJlc3VsdHMNCg0KIyMjIyBPdmVyYWxsDQpgYGB7cn0NCiNNb2RlbCBSZXN1bHRzDQpzdW1tYXJ5KFRvbF9TeW1fTTRfbG0pDQphbm92YShUb2xfU3ltX000X2xtKQ0KDQojRWZmZWN0IFNpemUgb2YgUHJlZGljdG9ycw0KZXRhX3NxdWFyZWQoVG9sX1N5bV9NNF9sbSwgcGFydGlhbD1GQUxTRSkNCg0KIyNTYXZlIG1vZGVsIHJlc3VsdHMNClRvbF9TeW1fTTRfbG0ucmVzPC1kYXRhLmZyYW1lKGFub3ZhKFRvbF9TeW1fTTRfbG0pKQ0KVG9sX1N5bV9NNF9sbS5yZXMkUHJlZGljdG9yPC1yb3duYW1lcyhUb2xfU3ltX000X2xtLnJlcykNClRvbF9TeW1fTTRfbG0ucmVzJEV0YVNxPC1jKGV0YV9zcXVhcmVkKFRvbF9TeW1fTTRfbG0sIHBhcnRpYWw9RkFMU0UpJEV0YTIsIE5BKQ0KVG9sX1N5bV9NNF9sbS5yZXMkUmVzcG9uc2U8LXJlcCgiU3ltYmlvbnRzIiwgbnJvdyhUb2xfU3ltX000X2xtLnJlcykpDQpUb2xfU3ltX000X2xtLnJlcyRUaW1lUDwtcmVwKCJNNCIsIG5yb3coVG9sX1N5bV9NNF9sbS5yZXMpKQ0KVG9sX1N5bV9NNF9sbS5yZXM8LVRvbF9TeW1fTTRfbG0ucmVzICU+JSBkcGx5cjo6cmVuYW1lKCBwLnZhbHVlID0gIlByLi5GLiIsIERGPSAiRGYiKQ0KDQpgYGANCg0KU2lnbmlmaWNhbnQgZWZmZWN0IG9mIFNpdGUgYW5kIEdlbm90eXBlLiBNYXJnaW5hbCBlZmZlY3QgKHA8MC4xKSBvZiBTaXRlICogR2Vub3R5cGUuIFN0aWxsIGNoZWNraW5nIFNpdGUqR2Vub3R5cGUgZm9yIGNvbXBhcmFiaWxpdHkgYWNyb3NzIFRpbWVwb2ludHMuDQoNCg0KDQojIyMjIFBhaXJ3aXNlDQpgYGB7cn0NCiNQYWlyd2lzZSBjb21wYXJpc29ucyBhY3Jvc3M6DQoNCiNHZW5vdHlwZXMgd2l0aGluIFNpdGVzDQplbW1lYW5zKFRvbF9TeW1fTTRfbG0sIHBhaXJ3aXNlfkdlbm90eXBlIHwgU2l0ZSkNCg0KI1NpdGVzIHdpdGhpbiBHZW5vdHlwZXMNCmVtbWVhbnMoVG9sX1N5bV9NNF9sbSwgcGFpcndpc2V+U2l0ZSB8IEdlbm90eXBlKQ0KDQojI1NhdmUgcC12YWx1ZXMNCg0KI0dlbm90eXBlcyB3aXRoaW4gU2l0ZXMNClRvbF9TeW1fTTRfbG0uZ2VubzwtZGF0YS5mcmFtZShlbW1lYW5zKFRvbF9TeW1fTTRfbG0sIHBhaXJ3aXNlfkdlbm90eXBlIHwgU2l0ZSkkY29udHJhc3RzKQ0KVG9sX1N5bV9NNF9sbS5nZW5vPC1Ub2xfU3ltX000X2xtLmdlbm8gJT4lIHNlcGFyYXRlKGNvbD1jb250cmFzdCwgaW50bz1jKCJncm91cDEiLCAiZ3JvdXAyIiksIHNlcD0iIC0gIiwgcmVtb3ZlPVRSVUUpDQpUb2xfU3ltX000X2xtLmdlbm8kZ3JvdXAxPC1wYXN0ZShUb2xfU3ltX000X2xtLmdlbm8kU2l0ZSwgVG9sX1N5bV9NNF9sbS5nZW5vJGdyb3VwMSwgc2VwPSJfIikNClRvbF9TeW1fTTRfbG0uZ2VubyRncm91cDI8LXBhc3RlKFRvbF9TeW1fTTRfbG0uZ2VubyRTaXRlLCBUb2xfU3ltX000X2xtLmdlbm8kZ3JvdXAyLCBzZXA9Il8iKQ0KDQojU2l0ZXMgd2l0aGluIEdlbm90eXBlcw0KVG9sX1N5bV9NNF9sbS5zaXRlPC1kYXRhLmZyYW1lKGVtbWVhbnMoVG9sX1N5bV9NNF9sbSwgcGFpcndpc2V+U2l0ZSB8IEdlbm90eXBlKSRjb250cmFzdHMpDQpUb2xfU3ltX000X2xtLnNpdGU8LVRvbF9TeW1fTTRfbG0uc2l0ZSAlPiUgc2VwYXJhdGUoY29sPWNvbnRyYXN0LCBpbnRvPWMoImdyb3VwMSIsICJncm91cDIiKSwgc2VwPSIgLSAiLCByZW1vdmU9VFJVRSkNClRvbF9TeW1fTTRfbG0uc2l0ZSRncm91cDE8LXBhc3RlKFRvbF9TeW1fTTRfbG0uc2l0ZSRncm91cDEsIFRvbF9TeW1fTTRfbG0uc2l0ZSRHZW5vdHlwZSwgc2VwPSJfIikNClRvbF9TeW1fTTRfbG0uc2l0ZSRncm91cDI8LXBhc3RlKFRvbF9TeW1fTTRfbG0uc2l0ZSRncm91cDIsIFRvbF9TeW1fTTRfbG0uc2l0ZSRHZW5vdHlwZSwgc2VwPSJfIikNCg0KI0Z1bGwgbGlzdCBvZiBwLXZhbHVlcw0KVG9sX1N5bV9NNF9sbS5wPC1yYmluZChUb2xfU3ltX000X2xtLmdlbm9bLGMoMToyLDQ6OCldLCBUb2xfU3ltX000X2xtLnNpdGVbLGMoMToyLDQ6OCldKQ0KVG9sX1N5bV9NNF9sbS5wPC1Ub2xfU3ltX000X2xtLnAgJT4lIGRwbHlyOjpyZW5hbWUoIHAgPSBwLnZhbHVlKQ0KDQojQWRkIFNpZ25pZmljYW5jZSBMZXZlbHMNClRvbF9TeW1fTTRfbG0ucCRTaWc8LWlmZWxzZShUb2xfU3ltX000X2xtLnAkcDwwLjAwMSwgIioqKiIsIGlmZWxzZShUb2xfU3ltX000X2xtLnAkcDwwLjAxLCAiKioiLCBpZmVsc2UoVG9sX1N5bV9NNF9sbS5wJHA8MC4wNSwgIioiLCBOQSkpKQ0KDQojU3BlY2lmeSBSZXNwb25zZSBhbmQgVGltZXBvaW50DQpUb2xfU3ltX000X2xtLnAkUmVzcG9uc2U8LXJlcCgiU3ltYmlvbnRzIiwgbnJvdyhUb2xfU3ltX000X2xtLnApKQ0KVG9sX1N5bV9NNF9sbS5wJFRpbWVQPC1yZXAoIk00IiwgbnJvdyhUb2xfU3ltX000X2xtLnApKQ0KDQpgYGANCg0KDQojIyMgUGxvdCBSZXRlbnRpb24gYnkgU2l0ZSBhbmQgR2Vub3R5cGUNCmBgYHtyfQ0KIyNTdW1tYXJ5IHN0YXRpc3RpY3MgYnkgU2l0ZSBhbmQgR2Vub3R5cGUNClRvbF9TeW1fTTRfU0c8LXN1bW1hcnlTRShUb2xEYXRhX000LCBtZWFzdXJldmFyPSJTeW0ucHJvcCIsIGdyb3VwdmFycz1jKCJTaXRlLkdlbm8iLCAiU2l0ZSIsICJHZW5vdHlwZSIpLCBuYS5ybT1UUlVFKQ0KDQojI1Bsb3QgQXZlcmFnZSBSZXRlbnRpb24gYWNyb3NzIFRyZWF0bWVudHMNClRvbF9TeW1fTTRfU0cucGxvdDwtZ2dwbG90KFRvbF9TeW1fTTRfU0csIGFlcyh4PVNpdGUuR2VubywgeT1TeW0ucHJvcCwgY29sb3VyPUdlbm90eXBlKSkgKyANCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1TeW0ucHJvcC1zZSwgeW1heD1TeW0ucHJvcCtzZSksIHdpZHRoPWNhcC5zeiwgbGluZXdpZHRoPWJhci5zeikrDQogIGdlb21fcG9pbnQoc2l6ZT1wb2ludC5zeikrIA0KICAgZ2d0aXRsZSgiU3ltYmlvbnQgUmV0ZW50aW9uIikrDQogIHRoZW1lX2NsYXNzaWMoKSsNCiAgdGhlbWUoIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIA0KICAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSBheGlzLnRpdGxlLnN6KSwgDQogICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksDQogICAgICAgIGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksIA0KICAgICAgICBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoc2l6ZT1sZWcudHh0LnN6KSwNCiAgICAgICAgbGVnZW5kLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPWxlZy50aXRsZS5zeiksIA0KICAgICAgICBsZWdlbmQuYm94LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoY29sb3IgPSAiYmxhY2siKSwNCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJib3R0b20iLCANCiAgICAgICAgbGVnZW5kLmRpcmVjdGlvbj0iaG9yaXpvbnRhbCIsDQogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHBsb3QudGl0bGUuc3osIGNvbG91cj0iYmxhY2siLCBoanVzdCA9IDAuNSkpKw0KICBsYWJzKHg9IiIsIHk9IlByb3BvcnRpb24gUmV0YWluZWQiKSsNCiAgeWxpbSgwLCAxLjUpKyANCiAgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHM9YygiIiwiS2xlaW4iLCIiLCIiLCJTb21ldGhpbmcgU3BlY2lhbCIsIiIpKSsNCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IEdlbm8uY29sb3JzLm8pKyANCiAgc3RhdF9wdmFsdWVfbWFudWFsKGRhdGE9VG9sX1N5bV9NNF9sbS5wLCAgeS5wb3NpdGlvbj0xLjEsIHN0ZXAuaW5jcmVhc2U9MC4xNSwgbGFiZWw9IlNpZyIsIGhpZGUubnM9VFJVRSk7IFRvbF9TeW1fTTRfU0cucGxvdA0KDQpgYGANCg0KDQojIFRoZXJtYWwgVG9sZXJhbmNlIENvbG9yIEZ1bGwgU2V0DQoNCiMjIEZ1bGwgU2V0DQoNCiMjIyBSdW4gTW9kZWwNCmBgYHtyfQ0KIyNDaGVjayBub3JtYWxpdHkNCmhpc3QoVG9sRGF0YSRTY29yZV9GdWxsLnByb3ApDQpzaGFwaXJvLnRlc3QoVG9sRGF0YSRTY29yZV9GdWxsLnByb3ApDQojTm90IE5vcm1hbA0KDQojI1RyeSBzcXVhcmUgdHJhbnNmb3JtYXRpb24NCmhpc3QoKFRvbERhdGEkU2NvcmVfRnVsbC5wcm9wKV4yKQ0Kc2hhcGlyby50ZXN0KChUb2xEYXRhJFNjb3JlX0Z1bGwucHJvcCleMikNCiNOb3Qgbm9ybWFsIA0KDQojI1RyeSBjdWJlZCB0cmFuc2Zvcm1hdGlvbg0KaGlzdCgoVG9sRGF0YSRTY29yZV9GdWxsLnByb3ApXjMpDQpzaGFwaXJvLnRlc3QoKFRvbERhdGEkU2NvcmVfRnVsbC5wcm9wKV4zKQ0KI05vdCBub3JtYWwgDQoNCg0KIyNNb2RlbCBhcyBhIGZ1bmN0aW9uIG9mIFNpdGUgYW5kIEdlbm90eXBlIGFuZCBUaW1lcG9pbnQNCiMjTW9kZWwgd2l0aCBubyB0cmFuc2Zvcm1hdGlvbiBhbmQgY2hlY2sgcmVzaWR1YWxzDQpUb2xfU2NvcmVGX2xtPC1sbShTY29yZV9GdWxsLnByb3B+U2l0ZStHZW5vdHlwZStUaW1lUCsgU2l0ZTpHZW5vdHlwZSArIFNpdGU6VGltZVAgKyBHZW5vdHlwZTpUaW1lUCwgZGF0YT1Ub2xEYXRhKQ0KDQpgYGANCg0KDQojIyMjIENoZWNrIFJlc2lkdWFscw0KYGBge3J9DQojI0NoZWNrIE5vcm1hbGl0eSBvZiBSZXNpZHVhbHMNCiNEaXN0cmlidXRpb24gDQpwbG90KGRlbnNpdHkocmVzaWQoVG9sX1Njb3JlRl9sbSkpKQ0KDQojUS1RIHBsb3QNCnFxbm9ybShyZXNpZChUb2xfU2NvcmVGX2xtKSk7IHFxbGluZShyZXNpZChUb2xfU2NvcmVGX2xtKSkNCg0KIyNDaGVjayBWYXJpYW5jZSBvZiBSZXNpZHVhbHMgYWNyb3NzIEZpdHRlZCBWYWx1ZXMNCnBsb3QoZml0dGVkKFRvbF9TY29yZUZfbG0pLCByZXNpZChUb2xfU2NvcmVGX2xtKSkNCg0KYGBgDQoNClJlc2lkdWFscyBhcmUgbm90IGdyZWF0LCBuZWVkIHRvIGNoZWNrIGZvciBvdGhlciBtb2RlbGluZyBvcHRpb25zIGZvciBDb2xvciBGdWxsIFNldC4NCg0KDQojIyMgTW9kZWwgUmVzdWx0cw0KDQpgYGB7cn0NCiNNb2RlbCBSZXN1bHRzDQpzdW1tYXJ5KFRvbF9TY29yZUZfbG0pDQphbm92YShUb2xfU2NvcmVGX2xtKQ0KDQojRWZmZWN0IFNpemUgb2YgUHJlZGljdG9ycw0KZXRhX3NxdWFyZWQoVG9sX1Njb3JlRl9sbSwgcGFydGlhbD1GQUxTRSkNCg0KIyNTYXZlIG1vZGVsIHJlc3VsdHMNClRvbF9TY29yZUZfbG0ucmVzPC1kYXRhLmZyYW1lKGFub3ZhKFRvbF9TY29yZUZfbG0pKQ0KVG9sX1Njb3JlRl9sbS5yZXMkUHJlZGljdG9yPC1yb3duYW1lcyhUb2xfU2NvcmVGX2xtLnJlcykNClRvbF9TY29yZUZfbG0ucmVzJEV0YVNxPC1jKGV0YV9zcXVhcmVkKFRvbF9TY29yZUZfbG0sIHBhcnRpYWw9RkFMU0UpJEV0YTIsIE5BKQ0KVG9sX1Njb3JlRl9sbS5yZXMkUmVzcG9uc2U8LXJlcCgiQ29sb3JfRnVsbFNldCIsIG5yb3coVG9sX1Njb3JlRl9sbS5yZXMpKQ0KVG9sX1Njb3JlRl9sbS5yZXM8LVRvbF9TY29yZUZfbG0ucmVzICU+JSBkcGx5cjo6cmVuYW1lKCBwLnZhbHVlID0gIlByLi5GLiIsIERGPSAiRGYiKQ0KDQpgYGANClN0cm9uZyBpbmZsdWVuY2Ugb2YgVGltZXBvaW50LCBpbmNsdWRpbmcgaW50ZXJhY3Rpb25zIHdpdGggR2Vub3R5cGUuIFdpbGwgYW5hbHl6ZSBlYWNoIFRpbWVwb2ludCBpbmRpdmlkdWFsbHkuIA0KDQoNCiMjIENvbG9yIFNjb3JlIEZ1bGwgU2V0IFN1bW1lciAxIFRpbWVwb2ludCBXMg0KDQojIyMgUnVuIE1vZGVsDQpgYGB7cn0NCiMjQ2hlY2sgbm9ybWFsaXR5DQpoaXN0KFRvbERhdGFfVzIkU2NvcmVfRnVsbC5wcm9wKQ0Kc2hhcGlyby50ZXN0KFRvbERhdGFfVzIkU2NvcmVfRnVsbC5wcm9wKQ0KI05vcm1hbA0KDQojI01vZGVsIGFzIGEgZnVuY3Rpb24gb2YgU2l0ZSBhbmQgR2Vub3R5cGUNClRvbF9TY29yZUZfVzJfbG08LWxtKFNjb3JlX0Z1bGwucHJvcH5TaXRlK0dlbm90eXBlK1NpdGU6R2Vub3R5cGUsIGRhdGE9VG9sRGF0YV9XMikNCg0KYGBgDQoNCg0KIyMjIyBDaGVjayBSZXNpZHVhbHMNCmBgYHtyfQ0KIyNDaGVjayBOb3JtYWxpdHkgb2YgUmVzaWR1YWxzDQojRGlzdHJpYnV0aW9uIA0KcGxvdChkZW5zaXR5KHJlc2lkKFRvbF9TY29yZUZfVzJfbG0pKSkNCg0KI1EtUSBwbG90DQpxcW5vcm0ocmVzaWQoVG9sX1Njb3JlRl9XMl9sbSkpOyBxcWxpbmUocmVzaWQoVG9sX1Njb3JlRl9XMl9sbSkpDQoNCiMjQ2hlY2sgVmFyaWFuY2Ugb2YgUmVzaWR1YWxzIGFjcm9zcyBGaXR0ZWQgVmFsdWVzDQpwbG90KGZpdHRlZChUb2xfU2NvcmVGX1cyX2xtKSwgcmVzaWQoVG9sX1Njb3JlRl9XMl9sbSkpDQoNCmBgYA0KDQoNCiMjIyBNb2RlbCBSZXN1bHRzDQoNCiMjIyMgT3ZlcmFsbA0KYGBge3J9DQojTW9kZWwgUmVzdWx0cw0Kc3VtbWFyeShUb2xfU2NvcmVGX1cyX2xtKQ0KYW5vdmEoVG9sX1Njb3JlRl9XMl9sbSkNCg0KI0VmZmVjdCBTaXplIG9mIFByZWRpY3RvcnMNCmV0YV9zcXVhcmVkKFRvbF9TY29yZUZfVzJfbG0sIHBhcnRpYWw9RkFMU0UpDQoNCiMjU2F2ZSBtb2RlbCByZXN1bHRzDQpUb2xfU2NvcmVGX1cyX2xtLnJlczwtZGF0YS5mcmFtZShhbm92YShUb2xfU2NvcmVGX1cyX2xtKSkNClRvbF9TY29yZUZfVzJfbG0ucmVzJFByZWRpY3Rvcjwtcm93bmFtZXMoVG9sX1Njb3JlRl9XMl9sbS5yZXMpDQpUb2xfU2NvcmVGX1cyX2xtLnJlcyRFdGFTcTwtYyhldGFfc3F1YXJlZChUb2xfU2NvcmVGX1cyX2xtLCBwYXJ0aWFsPUZBTFNFKSRFdGEyLCBOQSkNClRvbF9TY29yZUZfVzJfbG0ucmVzJFJlc3BvbnNlPC1yZXAoIkNvbG9yX0Z1bGxTZXQiLCBucm93KFRvbF9TY29yZUZfVzJfbG0ucmVzKSkNClRvbF9TY29yZUZfVzJfbG0ucmVzJFRpbWVQPC1yZXAoIlcyIiwgbnJvdyhUb2xfU2NvcmVGX1cyX2xtLnJlcykpDQpUb2xfU2NvcmVGX1cyX2xtLnJlczwtVG9sX1Njb3JlRl9XMl9sbS5yZXMgJT4lIGRwbHlyOjpyZW5hbWUoIHAudmFsdWUgPSAiUHIuLkYuIiwgREY9ICJEZiIpDQoNCmBgYA0KDQpTaWduaWZpY2FudCBlZmZlY3Qgb2YgU2l0ZSBhbmQgR2Vub3R5cGUuIFN0aWxsIGNoZWNraW5nIFNpdGUqR2Vub3R5cGUgZm9yIGNvbXBhcmFiaWxpdHkgYWNyb3NzIFRpbWVwb2ludHMuDQoNCg0KDQojIyMjIFBhaXJ3aXNlDQpgYGB7cn0NCiNQYWlyd2lzZSBjb21wYXJpc29ucyBhY3Jvc3M6DQoNCiNHZW5vdHlwZXMgd2l0aGluIFNpdGVzDQplbW1lYW5zKFRvbF9TY29yZUZfVzJfbG0sIHBhaXJ3aXNlfkdlbm90eXBlIHwgU2l0ZSkNCg0KI1NpdGVzIHdpdGhpbiBHZW5vdHlwZXMNCmVtbWVhbnMoVG9sX1Njb3JlRl9XMl9sbSwgcGFpcndpc2V+U2l0ZSB8IEdlbm90eXBlKQ0KDQojI1NhdmUgcC12YWx1ZXMNCg0KI0dlbm90eXBlcyB3aXRoaW4gU2l0ZXMNClRvbF9TY29yZUZfVzJfbG0uZ2VubzwtZGF0YS5mcmFtZShlbW1lYW5zKFRvbF9TY29yZUZfVzJfbG0sIHBhaXJ3aXNlfkdlbm90eXBlIHwgU2l0ZSkkY29udHJhc3RzKQ0KVG9sX1Njb3JlRl9XMl9sbS5nZW5vPC1Ub2xfU2NvcmVGX1cyX2xtLmdlbm8gJT4lIHNlcGFyYXRlKGNvbD1jb250cmFzdCwgaW50bz1jKCJncm91cDEiLCAiZ3JvdXAyIiksIHNlcD0iIC0gIiwgcmVtb3ZlPVRSVUUpDQpUb2xfU2NvcmVGX1cyX2xtLmdlbm8kZ3JvdXAxPC1wYXN0ZShUb2xfU2NvcmVGX1cyX2xtLmdlbm8kU2l0ZSwgVG9sX1Njb3JlRl9XMl9sbS5nZW5vJGdyb3VwMSwgc2VwPSJfIikNClRvbF9TY29yZUZfVzJfbG0uZ2VubyRncm91cDI8LXBhc3RlKFRvbF9TY29yZUZfVzJfbG0uZ2VubyRTaXRlLCBUb2xfU2NvcmVGX1cyX2xtLmdlbm8kZ3JvdXAyLCBzZXA9Il8iKQ0KDQojU2l0ZXMgd2l0aGluIEdlbm90eXBlcw0KVG9sX1Njb3JlRl9XMl9sbS5zaXRlPC1kYXRhLmZyYW1lKGVtbWVhbnMoVG9sX1Njb3JlRl9XMl9sbSwgcGFpcndpc2V+U2l0ZSB8IEdlbm90eXBlKSRjb250cmFzdHMpDQpUb2xfU2NvcmVGX1cyX2xtLnNpdGU8LVRvbF9TY29yZUZfVzJfbG0uc2l0ZSAlPiUgc2VwYXJhdGUoY29sPWNvbnRyYXN0LCBpbnRvPWMoImdyb3VwMSIsICJncm91cDIiKSwgc2VwPSIgLSAiLCByZW1vdmU9VFJVRSkNClRvbF9TY29yZUZfVzJfbG0uc2l0ZSRncm91cDE8LXBhc3RlKFRvbF9TY29yZUZfVzJfbG0uc2l0ZSRncm91cDEsIFRvbF9TY29yZUZfVzJfbG0uc2l0ZSRHZW5vdHlwZSwgc2VwPSJfIikNClRvbF9TY29yZUZfVzJfbG0uc2l0ZSRncm91cDI8LXBhc3RlKFRvbF9TY29yZUZfVzJfbG0uc2l0ZSRncm91cDIsIFRvbF9TY29yZUZfVzJfbG0uc2l0ZSRHZW5vdHlwZSwgc2VwPSJfIikNCg0KI0Z1bGwgbGlzdCBvZiBwLXZhbHVlcw0KVG9sX1Njb3JlRl9XMl9sbS5wPC1yYmluZChUb2xfU2NvcmVGX1cyX2xtLmdlbm9bLGMoMToyLDQ6OCldLCBUb2xfU2NvcmVGX1cyX2xtLnNpdGVbLGMoMToyLDQ6OCldKQ0KVG9sX1Njb3JlRl9XMl9sbS5wPC1Ub2xfU2NvcmVGX1cyX2xtLnAgJT4lIGRwbHlyOjpyZW5hbWUoIHAgPSBwLnZhbHVlKQ0KDQojQWRkIFNpZ25pZmljYW5jZSBMZXZlbHMNClRvbF9TY29yZUZfVzJfbG0ucCRTaWc8LWlmZWxzZShUb2xfU2NvcmVGX1cyX2xtLnAkcDwwLjAwMSwgIioqKiIsIGlmZWxzZShUb2xfU2NvcmVGX1cyX2xtLnAkcDwwLjAxLCAiKioiLCBpZmVsc2UoVG9sX1Njb3JlRl9XMl9sbS5wJHA8MC4wNSwgIioiLCBOQSkpKQ0KDQojU3BlY2lmeSBSZXNwb25zZSBhbmQgVGltZXBvaW50DQpUb2xfU2NvcmVGX1cyX2xtLnAkUmVzcG9uc2U8LXJlcCgiQ29sb3JfRnVsbFNldCIsIG5yb3coVG9sX1Njb3JlRl9XMl9sbS5wKSkNClRvbF9TY29yZUZfVzJfbG0ucCRUaW1lUDwtcmVwKCJXMiIsIG5yb3coVG9sX1Njb3JlRl9XMl9sbS5wKSkNCg0KYGBgDQoNCg0KIyMjIFBsb3QgUmV0ZW50aW9uIGJ5IFNpdGUgYW5kIEdlbm90eXBlDQpgYGB7cn0NCiMjU3VtbWFyeSBzdGF0aXN0aWNzIGJ5IFNpdGUgYW5kIEdlbm90eXBlDQpUb2xfU2NvcmVGX1cyX1NHPC1zdW1tYXJ5U0UoVG9sRGF0YV9XMiwgbWVhc3VyZXZhcj0iU2NvcmVfRnVsbC5wcm9wIiwgZ3JvdXB2YXJzPWMoIlNpdGUuR2VubyIsICJTaXRlIiwgIkdlbm90eXBlIiksIG5hLnJtPVRSVUUpDQoNCiMjUGxvdCBBdmVyYWdlIFJldGVudGlvbiBhY3Jvc3MgVHJlYXRtZW50cw0KVG9sX1Njb3JlRl9XMl9TRy5wbG90PC1nZ3Bsb3QoVG9sX1Njb3JlRl9XMl9TRywgYWVzKHg9U2l0ZS5HZW5vLCB5PVNjb3JlX0Z1bGwucHJvcCwgY29sb3VyPUdlbm90eXBlKSkgKyANCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1TY29yZV9GdWxsLnByb3Atc2UsIHltYXg9U2NvcmVfRnVsbC5wcm9wK3NlKSwgd2lkdGg9Y2FwLnN6LCBsaW5ld2lkdGg9YmFyLnN6KSsNCiAgZ2VvbV9wb2ludChzaXplPXBvaW50LnN6KSsgDQogICBnZ3RpdGxlKCJDb2xvciBSZXRlbnRpb24gRnVsbCBTZXQiKSsNCiAgdGhlbWVfY2xhc3NpYygpKw0KICB0aGVtZSggYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSBheGlzLnRpdGxlLnN6KSwgDQogICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IGF4aXMudGl0bGUuc3opLCANCiAgICAgICAgYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50eHQuc3osIGNvbG91cj0iYmxhY2siKSwNCiAgICAgICAgYXhpcy50ZXh0Lnk9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50eHQuc3osIGNvbG91cj0iYmxhY2siKSwgDQogICAgICAgIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPWxlZy50eHQuc3opLA0KICAgICAgICBsZWdlbmQudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnRpdGxlLnN6KSwgDQogICAgICAgIGxlZ2VuZC5ib3guYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChjb2xvciA9ICJibGFjayIpLA0KICAgICAgICBsZWdlbmQucG9zaXRpb249ImJvdHRvbSIsIA0KICAgICAgICBsZWdlbmQuZGlyZWN0aW9uPSJob3Jpem9udGFsIiwNCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gcGxvdC50aXRsZS5zeiwgY29sb3VyPSJibGFjayIsIGhqdXN0ID0gMC41KSkrDQogIGxhYnMoeD0iIiwgeT0iUHJvcG9ydGlvbiBSZXRhaW5lZCIpKw0KICB5bGltKDAsIDEuNSkrIA0KICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscz1jKCIiLCJLbGVpbiIsIiIsIiIsIlNvbWV0aGluZyBTcGVjaWFsIiwiIikpKw0KICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gR2Vuby5jb2xvcnMubykrIA0KICBzdGF0X3B2YWx1ZV9tYW51YWwoZGF0YT1Ub2xfU2NvcmVGX1cyX2xtLnAsICB5LnBvc2l0aW9uPTAuOSwgc3RlcC5pbmNyZWFzZT0wLjM1LCBsYWJlbD0iU2lnIiwgaGlkZS5ucz1UUlVFKTsgVG9sX1Njb3JlRl9XMl9TRy5wbG90DQoNCmBgYA0KDQoNCiMjIENvbG9yIFNjb3JlIEZ1bGwgU2V0IFN1bW1lciAyIFRpbWVwb2ludCBNMQ0KDQojIyMgUnVuIE1vZGVsDQpgYGB7cn0NCiMjQ2hlY2sgbm9ybWFsaXR5DQpoaXN0KFRvbERhdGFfTTEkU2NvcmVfRnVsbC5wcm9wKQ0Kc2hhcGlyby50ZXN0KFRvbERhdGFfTTEkU2NvcmVfRnVsbC5wcm9wKQ0KI05vdCBub3JtYWwNCg0KIyNUcnkgc3F1YXJlIHRyYW5zZm9ybWF0aW9uDQpoaXN0KChUb2xEYXRhX00xJFNjb3JlX0Z1bGwucHJvcCleMikNCnNoYXBpcm8udGVzdCgoVG9sRGF0YV9NMSRTY29yZV9GdWxsLnByb3ApXjIpDQojTm90IG5vcm1hbA0KDQojI1RyeSBjdWJlZCB0cmFuc2Zvcm1hdGlvbg0KaGlzdCgoVG9sRGF0YV9NMSRTY29yZV9GdWxsLnByb3ApXjMpDQpzaGFwaXJvLnRlc3QoKFRvbERhdGFfTTEkU2NvcmVfRnVsbC5wcm9wKV4zKQ0KI05vdCBub3JtYWwNCg0KIyNNb2RlbCBhcyBhIGZ1bmN0aW9uIG9mIFNpdGUgYW5kIEdlbm90eXBlDQojI01vZGVsIHdpdGggbm8gdHJhbnNmb3JtYXRpb24gYW5kIGNoZWNrIHJlc2lkdWFscw0KVG9sX1Njb3JlRl9NMV9sbTwtbG0oU2NvcmVfRnVsbC5wcm9wflNpdGUrR2Vub3R5cGUrU2l0ZTpHZW5vdHlwZSwgZGF0YT1Ub2xEYXRhX00xKQ0KDQpgYGANCg0KDQojIyMjIENoZWNrIFJlc2lkdWFscw0KYGBge3J9DQojI0NoZWNrIE5vcm1hbGl0eSBvZiBSZXNpZHVhbHMNCiNEaXN0cmlidXRpb24gDQpwbG90KGRlbnNpdHkocmVzaWQoVG9sX1Njb3JlRl9NMV9sbSkpKQ0KDQojUS1RIHBsb3QNCnFxbm9ybShyZXNpZChUb2xfU2NvcmVGX00xX2xtKSk7IHFxbGluZShyZXNpZChUb2xfU2NvcmVGX00xX2xtKSkNCg0KIyNDaGVjayBWYXJpYW5jZSBvZiBSZXNpZHVhbHMgYWNyb3NzIEZpdHRlZCBWYWx1ZXMNCnBsb3QoZml0dGVkKFRvbF9TY29yZUZfTTFfbG0pLCByZXNpZChUb2xfU2NvcmVGX00xX2xtKSkNCg0KYGBgDQoNCg0KIyMjIE1vZGVsIFJlc3VsdHMNCg0KIyMjIyBPdmVyYWxsDQpgYGB7cn0NCiNNb2RlbCBSZXN1bHRzDQpzdW1tYXJ5KFRvbF9TY29yZUZfTTFfbG0pDQphbm92YShUb2xfU2NvcmVGX00xX2xtKQ0KDQojRWZmZWN0IFNpemUgb2YgUHJlZGljdG9ycw0KZXRhX3NxdWFyZWQoVG9sX1Njb3JlRl9NMV9sbSwgcGFydGlhbD1GQUxTRSkNCg0KIyNTYXZlIG1vZGVsIHJlc3VsdHMNClRvbF9TY29yZUZfTTFfbG0ucmVzPC1kYXRhLmZyYW1lKGFub3ZhKFRvbF9TY29yZUZfTTFfbG0pKQ0KVG9sX1Njb3JlRl9NMV9sbS5yZXMkUHJlZGljdG9yPC1yb3duYW1lcyhUb2xfU2NvcmVGX00xX2xtLnJlcykNClRvbF9TY29yZUZfTTFfbG0ucmVzJEV0YVNxPC1jKGV0YV9zcXVhcmVkKFRvbF9TY29yZUZfTTFfbG0sIHBhcnRpYWw9RkFMU0UpJEV0YTIsIE5BKQ0KVG9sX1Njb3JlRl9NMV9sbS5yZXMkUmVzcG9uc2U8LXJlcCgiQ29sb3JfRnVsbFNldCIsIG5yb3coVG9sX1Njb3JlRl9NMV9sbS5yZXMpKQ0KVG9sX1Njb3JlRl9NMV9sbS5yZXMkVGltZVA8LXJlcCgiTTEiLCBucm93KFRvbF9TY29yZUZfTTFfbG0ucmVzKSkNClRvbF9TY29yZUZfTTFfbG0ucmVzPC1Ub2xfU2NvcmVGX00xX2xtLnJlcyAlPiUgZHBseXI6OnJlbmFtZSggcC52YWx1ZSA9ICJQci4uRi4iLCBERj0gIkRmIikNCg0KYGBgDQoNClNpZ25pZmljYW50IGVmZmVjdCBvZiBTaXRlIGFuZCBHZW5vdHlwZS4gU3RpbGwgY2hlY2tpbmcgU2l0ZSpHZW5vdHlwZSBmb3IgY29tcGFyYWJpbGl0eSBhY3Jvc3MgVGltZXBvaW50cy4NCg0KDQojIyMjIFBhaXJ3aXNlDQpgYGB7cn0NCiNQYWlyd2lzZSBjb21wYXJpc29ucyBhY3Jvc3M6DQoNCiNHZW5vdHlwZXMgd2l0aGluIFNpdGVzDQplbW1lYW5zKFRvbF9TY29yZUZfTTFfbG0sIHBhaXJ3aXNlfkdlbm90eXBlIHwgU2l0ZSkNCg0KI1NpdGVzIHdpdGhpbiBHZW5vdHlwZXMNCmVtbWVhbnMoVG9sX1Njb3JlRl9NMV9sbSwgcGFpcndpc2V+U2l0ZSB8IEdlbm90eXBlKQ0KDQojI1NhdmUgcC12YWx1ZXMNCg0KI0dlbm90eXBlcyB3aXRoaW4gU2l0ZXMNClRvbF9TY29yZUZfTTFfbG0uZ2VubzwtZGF0YS5mcmFtZShlbW1lYW5zKFRvbF9TY29yZUZfTTFfbG0sIHBhaXJ3aXNlfkdlbm90eXBlIHwgU2l0ZSkkY29udHJhc3RzKQ0KVG9sX1Njb3JlRl9NMV9sbS5nZW5vPC1Ub2xfU2NvcmVGX00xX2xtLmdlbm8gJT4lIHNlcGFyYXRlKGNvbD1jb250cmFzdCwgaW50bz1jKCJncm91cDEiLCAiZ3JvdXAyIiksIHNlcD0iIC0gIiwgcmVtb3ZlPVRSVUUpDQpUb2xfU2NvcmVGX00xX2xtLmdlbm8kZ3JvdXAxPC1wYXN0ZShUb2xfU2NvcmVGX00xX2xtLmdlbm8kU2l0ZSwgVG9sX1Njb3JlRl9NMV9sbS5nZW5vJGdyb3VwMSwgc2VwPSJfIikNClRvbF9TY29yZUZfTTFfbG0uZ2VubyRncm91cDI8LXBhc3RlKFRvbF9TY29yZUZfTTFfbG0uZ2VubyRTaXRlLCBUb2xfU2NvcmVGX00xX2xtLmdlbm8kZ3JvdXAyLCBzZXA9Il8iKQ0KDQojU2l0ZXMgd2l0aGluIEdlbm90eXBlcw0KVG9sX1Njb3JlRl9NMV9sbS5zaXRlPC1kYXRhLmZyYW1lKGVtbWVhbnMoVG9sX1Njb3JlRl9NMV9sbSwgcGFpcndpc2V+U2l0ZSB8IEdlbm90eXBlKSRjb250cmFzdHMpDQpUb2xfU2NvcmVGX00xX2xtLnNpdGU8LVRvbF9TY29yZUZfTTFfbG0uc2l0ZSAlPiUgc2VwYXJhdGUoY29sPWNvbnRyYXN0LCBpbnRvPWMoImdyb3VwMSIsICJncm91cDIiKSwgc2VwPSIgLSAiLCByZW1vdmU9VFJVRSkNClRvbF9TY29yZUZfTTFfbG0uc2l0ZSRncm91cDE8LXBhc3RlKFRvbF9TY29yZUZfTTFfbG0uc2l0ZSRncm91cDEsIFRvbF9TY29yZUZfTTFfbG0uc2l0ZSRHZW5vdHlwZSwgc2VwPSJfIikNClRvbF9TY29yZUZfTTFfbG0uc2l0ZSRncm91cDI8LXBhc3RlKFRvbF9TY29yZUZfTTFfbG0uc2l0ZSRncm91cDIsIFRvbF9TY29yZUZfTTFfbG0uc2l0ZSRHZW5vdHlwZSwgc2VwPSJfIikNCg0KI0Z1bGwgbGlzdCBvZiBwLXZhbHVlcw0KVG9sX1Njb3JlRl9NMV9sbS5wPC1yYmluZChUb2xfU2NvcmVGX00xX2xtLmdlbm9bLGMoMToyLDQ6OCldLCBUb2xfU2NvcmVGX00xX2xtLnNpdGVbLGMoMToyLDQ6OCldKQ0KVG9sX1Njb3JlRl9NMV9sbS5wPC1Ub2xfU2NvcmVGX00xX2xtLnAgJT4lIGRwbHlyOjpyZW5hbWUoIHAgPSBwLnZhbHVlKQ0KDQojQWRkIFNpZ25pZmljYW5jZSBMZXZlbHMNClRvbF9TY29yZUZfTTFfbG0ucCRTaWc8LWlmZWxzZShUb2xfU2NvcmVGX00xX2xtLnAkcDwwLjAwMSwgIioqKiIsIGlmZWxzZShUb2xfU2NvcmVGX00xX2xtLnAkcDwwLjAxLCAiKioiLCBpZmVsc2UoVG9sX1Njb3JlRl9NMV9sbS5wJHA8MC4wNSwgIioiLCBOQSkpKQ0KDQojU3BlY2lmeSBSZXNwb25zZSBhbmQgVGltZXBvaW50DQpUb2xfU2NvcmVGX00xX2xtLnAkUmVzcG9uc2U8LXJlcCgiQ29sb3JfRnVsbFNldCIsIG5yb3coVG9sX1Njb3JlRl9NMV9sbS5wKSkNClRvbF9TY29yZUZfTTFfbG0ucCRUaW1lUDwtcmVwKCJNMSIsIG5yb3coVG9sX1Njb3JlRl9NMV9sbS5wKSkNCg0KYGBgDQoNCg0KIyMjIFBsb3QgUmV0ZW50aW9uIGJ5IFNpdGUgYW5kIEdlbm90eXBlDQpgYGB7cn0NCiMjU3VtbWFyeSBzdGF0aXN0aWNzIGJ5IFNpdGUgYW5kIEdlbm90eXBlDQpUb2xfU2NvcmVGX00xX1NHPC1zdW1tYXJ5U0UoVG9sRGF0YV9NMSwgbWVhc3VyZXZhcj0iU2NvcmVfRnVsbC5wcm9wIiwgZ3JvdXB2YXJzPWMoIlNpdGUuR2VubyIsICJTaXRlIiwgIkdlbm90eXBlIiksIG5hLnJtPVRSVUUpDQoNCiMjUGxvdCBBdmVyYWdlIFJldGVudGlvbiBhY3Jvc3MgVHJlYXRtZW50cw0KVG9sX1Njb3JlRl9NMV9TRy5wbG90PC1nZ3Bsb3QoVG9sX1Njb3JlRl9NMV9TRywgYWVzKHg9U2l0ZS5HZW5vLCB5PVNjb3JlX0Z1bGwucHJvcCwgY29sb3VyPUdlbm90eXBlKSkgKyANCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1TY29yZV9GdWxsLnByb3Atc2UsIHltYXg9U2NvcmVfRnVsbC5wcm9wK3NlKSwgd2lkdGg9Y2FwLnN6LCBsaW5ld2lkdGg9YmFyLnN6KSsNCiAgZ2VvbV9wb2ludChzaXplPXBvaW50LnN6KSsgDQogICBnZ3RpdGxlKCJDb2xvciBSZXRlbnRpb24gRnVsbCBTZXQiKSsNCiAgdGhlbWVfY2xhc3NpYygpKw0KICB0aGVtZSggYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSBheGlzLnRpdGxlLnN6KSwgDQogICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IGF4aXMudGl0bGUuc3opLCANCiAgICAgICAgYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50eHQuc3osIGNvbG91cj0iYmxhY2siKSwNCiAgICAgICAgYXhpcy50ZXh0Lnk9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50eHQuc3osIGNvbG91cj0iYmxhY2siKSwgDQogICAgICAgIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPWxlZy50eHQuc3opLA0KICAgICAgICBsZWdlbmQudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnRpdGxlLnN6KSwgDQogICAgICAgIGxlZ2VuZC5ib3guYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChjb2xvciA9ICJibGFjayIpLA0KICAgICAgICBsZWdlbmQucG9zaXRpb249ImJvdHRvbSIsIA0KICAgICAgICBsZWdlbmQuZGlyZWN0aW9uPSJob3Jpem9udGFsIiwNCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gcGxvdC50aXRsZS5zeiwgY29sb3VyPSJibGFjayIsIGhqdXN0ID0gMC41KSkrDQogIGxhYnMoeD0iIiwgeT0iUHJvcG9ydGlvbiBSZXRhaW5lZCIpKw0KIHlsaW0oMCwgMS41KSsgDQogIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzPWMoIiIsIktsZWluIiwiIiwiIiwiU29tZXRoaW5nIFNwZWNpYWwiLCIiKSkrDQogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBHZW5vLmNvbG9ycy5vKSsgDQogIHN0YXRfcHZhbHVlX21hbnVhbChkYXRhPVRvbF9TY29yZUZfTTFfbG0ucCwgIHkucG9zaXRpb249MS4xLCBzdGVwLmluY3JlYXNlPTAuMiwgbGFiZWw9IlNpZyIsIGhpZGUubnM9VFJVRSk7IFRvbF9TY29yZUZfTTFfU0cucGxvdA0KDQpgYGANCg0KDQojIyBDb2xvciBTY29yZSBGdWxsIFNldCBXaW50ZXIgVGltZXBvaW50IE00DQoNCiMjIyBSdW4gTW9kZWwNCmBgYHtyfQ0KIyNDaGVjayBub3JtYWxpdHkNCmhpc3QoVG9sRGF0YV9NNCRTY29yZV9GdWxsLnByb3ApDQpzaGFwaXJvLnRlc3QoVG9sRGF0YV9NNCRTY29yZV9GdWxsLnByb3ApDQojTm90IE5vcm1hbA0KDQojI1RyeSBzcXVhcmUgdHJhbnNmb3JtYXRpb24NCmhpc3QoKFRvbERhdGFfTTQkU2NvcmVfRnVsbC5wcm9wKV4yKQ0Kc2hhcGlyby50ZXN0KChUb2xEYXRhX000JFNjb3JlX0Z1bGwucHJvcCleMikNCiNOb3QgTm9ybWFsDQoNCiMjVHJ5IGN1YmVkIHRyYW5zZm9ybWF0aW9uDQpoaXN0KChUb2xEYXRhX000JFNjb3JlX0Z1bGwucHJvcCleMykNCnNoYXBpcm8udGVzdCgoVG9sRGF0YV9NNCRTY29yZV9GdWxsLnByb3ApXjMpDQojTm90IE5vcm1hbA0KDQojI01vZGVsIGFzIGEgZnVuY3Rpb24gb2YgU2l0ZSBhbmQgR2Vub3R5cGUNCiMjTW9kZWwgd2l0aCBubyB0cmFuc2Zvcm1hdGlvbiBhbmQgY2hlY2sgcmVzaWR1YWxzDQpUb2xfU2NvcmVGX000X2xtPC1sbShTY29yZV9GdWxsLnByb3B+U2l0ZStHZW5vdHlwZStTaXRlOkdlbm90eXBlLCBkYXRhPVRvbERhdGFfTTQpDQoNCmBgYA0KDQoNCiMjIyMgQ2hlY2sgUmVzaWR1YWxzDQpgYGB7cn0NCiMjQ2hlY2sgTm9ybWFsaXR5IG9mIFJlc2lkdWFscw0KI0Rpc3RyaWJ1dGlvbiANCnBsb3QoZGVuc2l0eShyZXNpZChUb2xfU2NvcmVGX000X2xtKSkpDQoNCiNRLVEgcGxvdA0KcXFub3JtKHJlc2lkKFRvbF9TY29yZUZfTTRfbG0pKTsgcXFsaW5lKHJlc2lkKFRvbF9TY29yZUZfTTRfbG0pKQ0KDQojI0NoZWNrIFZhcmlhbmNlIG9mIFJlc2lkdWFscyBhY3Jvc3MgRml0dGVkIFZhbHVlcw0KcGxvdChmaXR0ZWQoVG9sX1Njb3JlRl9NNF9sbSksIHJlc2lkKFRvbF9TY29yZUZfTTRfbG0pKQ0KDQpgYGANCg0KDQojIyMgTW9kZWwgUmVzdWx0cw0KDQojIyMjIE92ZXJhbGwNCmBgYHtyfQ0KI01vZGVsIFJlc3VsdHMNCnN1bW1hcnkoVG9sX1Njb3JlRl9NNF9sbSkNCmFub3ZhKFRvbF9TY29yZUZfTTRfbG0pDQoNCiNFZmZlY3QgU2l6ZSBvZiBQcmVkaWN0b3JzDQpldGFfc3F1YXJlZChUb2xfU2NvcmVGX000X2xtLCBwYXJ0aWFsPUZBTFNFKQ0KDQojI1NhdmUgbW9kZWwgcmVzdWx0cw0KVG9sX1Njb3JlRl9NNF9sbS5yZXM8LWRhdGEuZnJhbWUoYW5vdmEoVG9sX1Njb3JlRl9NNF9sbSkpDQpUb2xfU2NvcmVGX000X2xtLnJlcyRQcmVkaWN0b3I8LXJvd25hbWVzKFRvbF9TY29yZUZfTTRfbG0ucmVzKQ0KVG9sX1Njb3JlRl9NNF9sbS5yZXMkRXRhU3E8LWMoZXRhX3NxdWFyZWQoVG9sX1Njb3JlRl9NNF9sbSwgcGFydGlhbD1GQUxTRSkkRXRhMiwgTkEpDQpUb2xfU2NvcmVGX000X2xtLnJlcyRSZXNwb25zZTwtcmVwKCJDb2xvcl9GdWxsU2V0IiwgbnJvdyhUb2xfU2NvcmVGX000X2xtLnJlcykpDQpUb2xfU2NvcmVGX000X2xtLnJlcyRUaW1lUDwtcmVwKCJNNCIsIG5yb3coVG9sX1Njb3JlRl9NNF9sbS5yZXMpKQ0KVG9sX1Njb3JlRl9NNF9sbS5yZXM8LVRvbF9TY29yZUZfTTRfbG0ucmVzICU+JSBkcGx5cjo6cmVuYW1lKCBwLnZhbHVlID0gIlByLi5GLiIsIERGPSAiRGYiKQ0KDQpgYGANCg0KU2lnbmlmaWNhbnQgZWZmZWN0IG9mIFNpdGUgYW5kIEdlbm90eXBlLiBTdGlsbCBjaGVja2luZyBTaXRlKkdlbm90eXBlIGZvciBjb21wYXJhYmlsaXR5IGFjcm9zcyBUaW1lcG9pbnRzLg0KDQoNCg0KIyMjIyBQYWlyd2lzZQ0KYGBge3J9DQojUGFpcndpc2UgY29tcGFyaXNvbnMgYWNyb3NzOg0KDQojR2Vub3R5cGVzIHdpdGhpbiBTaXRlcw0KZW1tZWFucyhUb2xfU2NvcmVGX000X2xtLCBwYWlyd2lzZX5HZW5vdHlwZSB8IFNpdGUpDQoNCiNTaXRlcyB3aXRoaW4gR2Vub3R5cGVzDQplbW1lYW5zKFRvbF9TY29yZUZfTTRfbG0sIHBhaXJ3aXNlflNpdGUgfCBHZW5vdHlwZSkNCg0KIyNTYXZlIHAtdmFsdWVzDQoNCiNHZW5vdHlwZXMgd2l0aGluIFNpdGVzDQpUb2xfU2NvcmVGX000X2xtLmdlbm88LWRhdGEuZnJhbWUoZW1tZWFucyhUb2xfU2NvcmVGX000X2xtLCBwYWlyd2lzZX5HZW5vdHlwZSB8IFNpdGUpJGNvbnRyYXN0cykNClRvbF9TY29yZUZfTTRfbG0uZ2VubzwtVG9sX1Njb3JlRl9NNF9sbS5nZW5vICU+JSBzZXBhcmF0ZShjb2w9Y29udHJhc3QsIGludG89YygiZ3JvdXAxIiwgImdyb3VwMiIpLCBzZXA9IiAtICIsIHJlbW92ZT1UUlVFKQ0KVG9sX1Njb3JlRl9NNF9sbS5nZW5vJGdyb3VwMTwtcGFzdGUoVG9sX1Njb3JlRl9NNF9sbS5nZW5vJFNpdGUsIFRvbF9TY29yZUZfTTRfbG0uZ2VubyRncm91cDEsIHNlcD0iXyIpDQpUb2xfU2NvcmVGX000X2xtLmdlbm8kZ3JvdXAyPC1wYXN0ZShUb2xfU2NvcmVGX000X2xtLmdlbm8kU2l0ZSwgVG9sX1Njb3JlRl9NNF9sbS5nZW5vJGdyb3VwMiwgc2VwPSJfIikNCg0KI1NpdGVzIHdpdGhpbiBHZW5vdHlwZXMNClRvbF9TY29yZUZfTTRfbG0uc2l0ZTwtZGF0YS5mcmFtZShlbW1lYW5zKFRvbF9TY29yZUZfTTRfbG0sIHBhaXJ3aXNlflNpdGUgfCBHZW5vdHlwZSkkY29udHJhc3RzKQ0KVG9sX1Njb3JlRl9NNF9sbS5zaXRlPC1Ub2xfU2NvcmVGX000X2xtLnNpdGUgJT4lIHNlcGFyYXRlKGNvbD1jb250cmFzdCwgaW50bz1jKCJncm91cDEiLCAiZ3JvdXAyIiksIHNlcD0iIC0gIiwgcmVtb3ZlPVRSVUUpDQpUb2xfU2NvcmVGX000X2xtLnNpdGUkZ3JvdXAxPC1wYXN0ZShUb2xfU2NvcmVGX000X2xtLnNpdGUkZ3JvdXAxLCBUb2xfU2NvcmVGX000X2xtLnNpdGUkR2Vub3R5cGUsIHNlcD0iXyIpDQpUb2xfU2NvcmVGX000X2xtLnNpdGUkZ3JvdXAyPC1wYXN0ZShUb2xfU2NvcmVGX000X2xtLnNpdGUkZ3JvdXAyLCBUb2xfU2NvcmVGX000X2xtLnNpdGUkR2Vub3R5cGUsIHNlcD0iXyIpDQoNCiNGdWxsIGxpc3Qgb2YgcC12YWx1ZXMNClRvbF9TY29yZUZfTTRfbG0ucDwtcmJpbmQoVG9sX1Njb3JlRl9NNF9sbS5nZW5vWyxjKDE6Miw0OjgpXSwgVG9sX1Njb3JlRl9NNF9sbS5zaXRlWyxjKDE6Miw0OjgpXSkNClRvbF9TY29yZUZfTTRfbG0ucDwtVG9sX1Njb3JlRl9NNF9sbS5wICU+JSBkcGx5cjo6cmVuYW1lKCBwID0gcC52YWx1ZSkNCg0KI0FkZCBTaWduaWZpY2FuY2UgTGV2ZWxzDQpUb2xfU2NvcmVGX000X2xtLnAkU2lnPC1pZmVsc2UoVG9sX1Njb3JlRl9NNF9sbS5wJHA8MC4wMDEsICIqKioiLCBpZmVsc2UoVG9sX1Njb3JlRl9NNF9sbS5wJHA8MC4wMSwgIioqIiwgaWZlbHNlKFRvbF9TY29yZUZfTTRfbG0ucCRwPDAuMDUsICIqIiwgTkEpKSkNCg0KI1NwZWNpZnkgUmVzcG9uc2UgYW5kIFRpbWVwb2ludA0KVG9sX1Njb3JlRl9NNF9sbS5wJFJlc3BvbnNlPC1yZXAoIkNvbG9yX0Z1bGxTZXQiLCBucm93KFRvbF9TY29yZUZfTTRfbG0ucCkpDQpUb2xfU2NvcmVGX000X2xtLnAkVGltZVA8LXJlcCgiTTQiLCBucm93KFRvbF9TY29yZUZfTTRfbG0ucCkpDQoNCmBgYA0KDQoNCiMjIyBQbG90IFJldGVudGlvbiBieSBTaXRlIGFuZCBHZW5vdHlwZQ0KYGBge3J9DQojI1N1bW1hcnkgc3RhdGlzdGljcyBieSBTaXRlIGFuZCBHZW5vdHlwZQ0KVG9sX1Njb3JlRl9NNF9TRzwtc3VtbWFyeVNFKFRvbERhdGFfTTQsIG1lYXN1cmV2YXI9IlNjb3JlX0Z1bGwucHJvcCIsIGdyb3VwdmFycz1jKCJTaXRlLkdlbm8iLCAiU2l0ZSIsICJHZW5vdHlwZSIpLCBuYS5ybT1UUlVFKQ0KDQojI1Bsb3QgQXZlcmFnZSBSZXRlbnRpb24gYWNyb3NzIFRyZWF0bWVudHMNClRvbF9TY29yZUZfTTRfU0cucGxvdDwtZ2dwbG90KFRvbF9TY29yZUZfTTRfU0csIGFlcyh4PVNpdGUuR2VubywgeT1TY29yZV9GdWxsLnByb3AsIGNvbG91cj1HZW5vdHlwZSkpICsgDQogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49U2NvcmVfRnVsbC5wcm9wLXNlLCB5bWF4PVNjb3JlX0Z1bGwucHJvcCtzZSksIHdpZHRoPWNhcC5zeiwgbGluZXdpZHRoPWJhci5zeikrDQogIGdlb21fcG9pbnQoc2l6ZT1wb2ludC5zeikrIA0KICAgZ2d0aXRsZSgiQ29sb3IgUmV0ZW50aW9uIEZ1bGwgU2V0IikrDQogIHRoZW1lX2NsYXNzaWMoKSsNCiAgdGhlbWUoIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIA0KICAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSBheGlzLnRpdGxlLnN6KSwgDQogICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksDQogICAgICAgIGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksIA0KICAgICAgICBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoc2l6ZT1sZWcudHh0LnN6KSwNCiAgICAgICAgbGVnZW5kLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPWxlZy50aXRsZS5zeiksIA0KICAgICAgICBsZWdlbmQuYm94LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoY29sb3IgPSAiYmxhY2siKSwNCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJib3R0b20iLCANCiAgICAgICAgbGVnZW5kLmRpcmVjdGlvbj0iaG9yaXpvbnRhbCIsDQogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHBsb3QudGl0bGUuc3osIGNvbG91cj0iYmxhY2siLCBoanVzdCA9IDAuNSkpKw0KICBsYWJzKHg9IiIsIHk9IlByb3BvcnRpb24gUmV0YWluZWQiKSsNCiAgeWxpbSgwLCAxLjUpKyANCiAgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHM9YygiIiwiS2xlaW4iLCIiLCIiLCJTb21ldGhpbmcgU3BlY2lhbCIsIiIpKSsNCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IEdlbm8uY29sb3JzLm8pKyANCiAgc3RhdF9wdmFsdWVfbWFudWFsKGRhdGE9VG9sX1Njb3JlRl9NNF9sbS5wLCAgeS5wb3NpdGlvbj0xLjEsIHN0ZXAuaW5jcmVhc2U9MC4yMiwgbGFiZWw9IlNpZyIsIGhpZGUubnM9VFJVRSk7IFRvbF9TY29yZUZfTTRfU0cucGxvdA0KDQpgYGANCg0KDQojIFRoZXJtYWwgVG9sZXJhbmNlIENvbG9yIGJ5IFRpbWVwb2ludA0KDQojIyBGdWxsIFNldA0KDQojIyMgUnVuIE1vZGVsDQpgYGB7cn0NCiMjQ2hlY2sgbm9ybWFsaXR5DQpoaXN0KFRvbERhdGEkU2NvcmVfVFAucHJvcCkNCnNoYXBpcm8udGVzdChUb2xEYXRhJFNjb3JlX1RQLnByb3ApDQojTm90IE5vcm1hbA0KDQojI1RyeSBzcXVhcmUgdHJhbnNmb3JtYXRpb24NCmhpc3QoKFRvbERhdGEkU2NvcmVfVFAucHJvcCleMikNCnNoYXBpcm8udGVzdCgoVG9sRGF0YSRTY29yZV9UUC5wcm9wKV4yKQ0KI05vdCBub3JtYWwgDQoNCiMjVHJ5IGN1YmVkIHRyYW5zZm9ybWF0aW9uDQpoaXN0KChUb2xEYXRhJFNjb3JlX1RQLnByb3ApXjMpDQpzaGFwaXJvLnRlc3QoKFRvbERhdGEkU2NvcmVfVFAucHJvcCleMykNCiNOb3Qgbm9ybWFsIA0KDQoNCiMjTW9kZWwgYXMgYSBmdW5jdGlvbiBvZiBTaXRlIGFuZCBHZW5vdHlwZSBhbmQgVGltZXBvaW50DQojI01vZGVsIHdpdGggbm8gdHJhbnNmb3JtYXRpb24gYW5kIGNoZWNrIHJlc2lkdWFscw0KVG9sX1Njb3JlVFBfbG08LWxtKFNjb3JlX1RQLnByb3B+U2l0ZStHZW5vdHlwZStUaW1lUCsgU2l0ZTpHZW5vdHlwZSArIFNpdGU6VGltZVAgKyBHZW5vdHlwZTpUaW1lUCwgZGF0YT1Ub2xEYXRhKQ0KDQpgYGANCg0KDQojIyMjIENoZWNrIFJlc2lkdWFscw0KYGBge3J9DQojI0NoZWNrIE5vcm1hbGl0eSBvZiBSZXNpZHVhbHMNCiNEaXN0cmlidXRpb24gDQpwbG90KGRlbnNpdHkocmVzaWQoVG9sX1Njb3JlVFBfbG0pKSkNCg0KI1EtUSBwbG90DQpxcW5vcm0ocmVzaWQoVG9sX1Njb3JlVFBfbG0pKTsgcXFsaW5lKHJlc2lkKFRvbF9TY29yZVRQX2xtKSkNCg0KIyNDaGVjayBWYXJpYW5jZSBvZiBSZXNpZHVhbHMgYWNyb3NzIEZpdHRlZCBWYWx1ZXMNCnBsb3QoZml0dGVkKFRvbF9TY29yZVRQX2xtKSwgcmVzaWQoVG9sX1Njb3JlVFBfbG0pKQ0KDQpgYGANCg0KUmVzaWR1YWxzIGFyZSBub3QgZ3JlYXQsIG5lZWQgdG8gY2hlY2sgZm9yIG90aGVyIG1vZGVsaW5nIG9wdGlvbnMgZm9yIENvbG9yIGJ5IFRpbWVwb2ludC4NCg0KDQojIyMgTW9kZWwgUmVzdWx0cw0KDQpgYGB7cn0NCiNNb2RlbCBSZXN1bHRzDQpzdW1tYXJ5KFRvbF9TY29yZVRQX2xtKQ0KYW5vdmEoVG9sX1Njb3JlVFBfbG0pDQoNCiNFZmZlY3QgU2l6ZSBvZiBQcmVkaWN0b3JzDQpldGFfc3F1YXJlZChUb2xfU2NvcmVUUF9sbSwgcGFydGlhbD1GQUxTRSkNCg0KIyNTYXZlIG1vZGVsIHJlc3VsdHMNClRvbF9TY29yZVRQX2xtLnJlczwtZGF0YS5mcmFtZShhbm92YShUb2xfU2NvcmVUUF9sbSkpDQpUb2xfU2NvcmVUUF9sbS5yZXMkUHJlZGljdG9yPC1yb3duYW1lcyhUb2xfU2NvcmVUUF9sbS5yZXMpDQpUb2xfU2NvcmVUUF9sbS5yZXMkRXRhU3E8LWMoZXRhX3NxdWFyZWQoVG9sX1Njb3JlVFBfbG0sIHBhcnRpYWw9RkFMU0UpJEV0YTIsIE5BKQ0KVG9sX1Njb3JlVFBfbG0ucmVzJFJlc3BvbnNlPC1yZXAoIkNvbG9yX1RQIiwgbnJvdyhUb2xfU2NvcmVUUF9sbS5yZXMpKQ0KVG9sX1Njb3JlVFBfbG0ucmVzPC1Ub2xfU2NvcmVUUF9sbS5yZXMgJT4lIGRwbHlyOjpyZW5hbWUoIHAudmFsdWUgPSAiUHIuLkYuIiwgREY9ICJEZiIpDQoNCmBgYA0KU3Ryb25nIGluZmx1ZW5jZSBvZiBUaW1lcG9pbnQsIGluY2x1ZGluZyBpbnRlcmFjdGlvbnMgd2l0aCB2YXJpYWJsZXMgb2YgaW50ZXJlc3QsIFNpdGUgYW5kIEdlbm90eXBlLiBXaWxsIGFuYWx5emUgZWFjaCBUaW1lcG9pbnQgaW5kaXZpZHVhbGx5LiANCg0KDQojIyBDb2xvciBTY29yZSBieSBUaW1lcG9pbnQgU3VtbWVyIDEgVGltZXBvaW50IFcyDQoNCiMjIyBSdW4gTW9kZWwNCmBgYHtyfQ0KIyNDaGVjayBub3JtYWxpdHkNCmhpc3QoVG9sRGF0YV9XMiRTY29yZV9UUC5wcm9wKQ0Kc2hhcGlyby50ZXN0KFRvbERhdGFfVzIkU2NvcmVfVFAucHJvcCkNCiNOb3JtYWwNCg0KIyNNb2RlbCBhcyBhIGZ1bmN0aW9uIG9mIFNpdGUgYW5kIEdlbm90eXBlDQpUb2xfU2NvcmVUUF9XMl9sbTwtbG0oU2NvcmVfVFAucHJvcH5TaXRlK0dlbm90eXBlK1NpdGU6R2Vub3R5cGUsIGRhdGE9VG9sRGF0YV9XMikNCg0KYGBgDQoNCg0KIyMjIyBDaGVjayBSZXNpZHVhbHMNCmBgYHtyfQ0KIyNDaGVjayBOb3JtYWxpdHkgb2YgUmVzaWR1YWxzDQojRGlzdHJpYnV0aW9uIA0KcGxvdChkZW5zaXR5KHJlc2lkKFRvbF9TY29yZVRQX1cyX2xtKSkpDQoNCiNRLVEgcGxvdA0KcXFub3JtKHJlc2lkKFRvbF9TY29yZVRQX1cyX2xtKSk7IHFxbGluZShyZXNpZChUb2xfU2NvcmVUUF9XMl9sbSkpDQoNCiMjQ2hlY2sgVmFyaWFuY2Ugb2YgUmVzaWR1YWxzIGFjcm9zcyBGaXR0ZWQgVmFsdWVzDQpwbG90KGZpdHRlZChUb2xfU2NvcmVUUF9XMl9sbSksIHJlc2lkKFRvbF9TY29yZVRQX1cyX2xtKSkNCg0KYGBgDQoNCg0KIyMjIE1vZGVsIFJlc3VsdHMNCg0KIyMjIyBPdmVyYWxsDQpgYGB7cn0NCiNNb2RlbCBSZXN1bHRzDQpzdW1tYXJ5KFRvbF9TY29yZVRQX1cyX2xtKQ0KYW5vdmEoVG9sX1Njb3JlVFBfVzJfbG0pDQoNCiNFZmZlY3QgU2l6ZSBvZiBQcmVkaWN0b3JzDQpldGFfc3F1YXJlZChUb2xfU2NvcmVUUF9XMl9sbSwgcGFydGlhbD1GQUxTRSkNCg0KIyNTYXZlIG1vZGVsIHJlc3VsdHMNClRvbF9TY29yZVRQX1cyX2xtLnJlczwtZGF0YS5mcmFtZShhbm92YShUb2xfU2NvcmVUUF9XMl9sbSkpDQpUb2xfU2NvcmVUUF9XMl9sbS5yZXMkUHJlZGljdG9yPC1yb3duYW1lcyhUb2xfU2NvcmVUUF9XMl9sbS5yZXMpDQpUb2xfU2NvcmVUUF9XMl9sbS5yZXMkRXRhU3E8LWMoZXRhX3NxdWFyZWQoVG9sX1Njb3JlVFBfVzJfbG0sIHBhcnRpYWw9RkFMU0UpJEV0YTIsIE5BKQ0KVG9sX1Njb3JlVFBfVzJfbG0ucmVzJFJlc3BvbnNlPC1yZXAoIkNvbG9yX1RQIiwgbnJvdyhUb2xfU2NvcmVUUF9XMl9sbS5yZXMpKQ0KVG9sX1Njb3JlVFBfVzJfbG0ucmVzJFRpbWVQPC1yZXAoIlcyIiwgbnJvdyhUb2xfU2NvcmVUUF9XMl9sbS5yZXMpKQ0KVG9sX1Njb3JlVFBfVzJfbG0ucmVzPC1Ub2xfU2NvcmVUUF9XMl9sbS5yZXMgJT4lIGRwbHlyOjpyZW5hbWUoIHAudmFsdWUgPSAiUHIuLkYuIiwgREY9ICJEZiIpDQoNCmBgYA0KDQpTaWduaWZpY2FudCBlZmZlY3Qgb2YgU2l0ZSBhbmQgR2Vub3R5cGUuIFN0aWxsIGNoZWNraW5nIFNpdGUqR2Vub3R5cGUgZm9yIGNvbXBhcmFiaWxpdHkgYWNyb3NzIFRpbWVwb2ludHMuDQoNCg0KDQojIyMjIFBhaXJ3aXNlDQpgYGB7cn0NCiNQYWlyd2lzZSBjb21wYXJpc29ucyBhY3Jvc3M6DQoNCiNHZW5vdHlwZXMgd2l0aGluIFNpdGVzDQplbW1lYW5zKFRvbF9TY29yZVRQX1cyX2xtLCBwYWlyd2lzZX5HZW5vdHlwZSB8IFNpdGUpDQoNCiNTaXRlcyB3aXRoaW4gR2Vub3R5cGVzDQplbW1lYW5zKFRvbF9TY29yZVRQX1cyX2xtLCBwYWlyd2lzZX5TaXRlIHwgR2Vub3R5cGUpDQoNCiMjU2F2ZSBwLXZhbHVlcw0KDQojR2Vub3R5cGVzIHdpdGhpbiBTaXRlcw0KVG9sX1Njb3JlVFBfVzJfbG0uZ2VubzwtZGF0YS5mcmFtZShlbW1lYW5zKFRvbF9TY29yZVRQX1cyX2xtLCBwYWlyd2lzZX5HZW5vdHlwZSB8IFNpdGUpJGNvbnRyYXN0cykNClRvbF9TY29yZVRQX1cyX2xtLmdlbm88LVRvbF9TY29yZVRQX1cyX2xtLmdlbm8gJT4lIHNlcGFyYXRlKGNvbD1jb250cmFzdCwgaW50bz1jKCJncm91cDEiLCAiZ3JvdXAyIiksIHNlcD0iIC0gIiwgcmVtb3ZlPVRSVUUpDQpUb2xfU2NvcmVUUF9XMl9sbS5nZW5vJGdyb3VwMTwtcGFzdGUoVG9sX1Njb3JlVFBfVzJfbG0uZ2VubyRTaXRlLCBUb2xfU2NvcmVUUF9XMl9sbS5nZW5vJGdyb3VwMSwgc2VwPSJfIikNClRvbF9TY29yZVRQX1cyX2xtLmdlbm8kZ3JvdXAyPC1wYXN0ZShUb2xfU2NvcmVUUF9XMl9sbS5nZW5vJFNpdGUsIFRvbF9TY29yZVRQX1cyX2xtLmdlbm8kZ3JvdXAyLCBzZXA9Il8iKQ0KDQojU2l0ZXMgd2l0aGluIEdlbm90eXBlcw0KVG9sX1Njb3JlVFBfVzJfbG0uc2l0ZTwtZGF0YS5mcmFtZShlbW1lYW5zKFRvbF9TY29yZVRQX1cyX2xtLCBwYWlyd2lzZX5TaXRlIHwgR2Vub3R5cGUpJGNvbnRyYXN0cykNClRvbF9TY29yZVRQX1cyX2xtLnNpdGU8LVRvbF9TY29yZVRQX1cyX2xtLnNpdGUgJT4lIHNlcGFyYXRlKGNvbD1jb250cmFzdCwgaW50bz1jKCJncm91cDEiLCAiZ3JvdXAyIiksIHNlcD0iIC0gIiwgcmVtb3ZlPVRSVUUpDQpUb2xfU2NvcmVUUF9XMl9sbS5zaXRlJGdyb3VwMTwtcGFzdGUoVG9sX1Njb3JlVFBfVzJfbG0uc2l0ZSRncm91cDEsIFRvbF9TY29yZVRQX1cyX2xtLnNpdGUkR2Vub3R5cGUsIHNlcD0iXyIpDQpUb2xfU2NvcmVUUF9XMl9sbS5zaXRlJGdyb3VwMjwtcGFzdGUoVG9sX1Njb3JlVFBfVzJfbG0uc2l0ZSRncm91cDIsIFRvbF9TY29yZVRQX1cyX2xtLnNpdGUkR2Vub3R5cGUsIHNlcD0iXyIpDQoNCiNGdWxsIGxpc3Qgb2YgcC12YWx1ZXMNClRvbF9TY29yZVRQX1cyX2xtLnA8LXJiaW5kKFRvbF9TY29yZVRQX1cyX2xtLmdlbm9bLGMoMToyLDQ6OCldLCBUb2xfU2NvcmVUUF9XMl9sbS5zaXRlWyxjKDE6Miw0OjgpXSkNClRvbF9TY29yZVRQX1cyX2xtLnA8LVRvbF9TY29yZVRQX1cyX2xtLnAgJT4lIGRwbHlyOjpyZW5hbWUoIHAgPSBwLnZhbHVlKQ0KDQojQWRkIFNpZ25pZmljYW5jZSBMZXZlbHMNClRvbF9TY29yZVRQX1cyX2xtLnAkU2lnPC1pZmVsc2UoVG9sX1Njb3JlVFBfVzJfbG0ucCRwPDAuMDAxLCAiKioqIiwgaWZlbHNlKFRvbF9TY29yZVRQX1cyX2xtLnAkcDwwLjAxLCAiKioiLCBpZmVsc2UoVG9sX1Njb3JlVFBfVzJfbG0ucCRwPDAuMDUsICIqIiwgTkEpKSkNCg0KI1NwZWNpZnkgUmVzcG9uc2UgYW5kIFRpbWVwb2ludA0KVG9sX1Njb3JlVFBfVzJfbG0ucCRSZXNwb25zZTwtcmVwKCJDb2xvcl9UUCIsIG5yb3coVG9sX1Njb3JlVFBfVzJfbG0ucCkpDQpUb2xfU2NvcmVUUF9XMl9sbS5wJFRpbWVQPC1yZXAoIlcyIiwgbnJvdyhUb2xfU2NvcmVUUF9XMl9sbS5wKSkNCg0KYGBgDQoNCg0KIyMjIFBsb3QgUmV0ZW50aW9uIGJ5IFNpdGUgYW5kIEdlbm90eXBlDQpgYGB7cn0NCiMjU3VtbWFyeSBzdGF0aXN0aWNzIGJ5IFNpdGUgYW5kIEdlbm90eXBlDQpUb2xfU2NvcmVUUF9XMl9TRzwtc3VtbWFyeVNFKFRvbERhdGFfVzIsIG1lYXN1cmV2YXI9IlNjb3JlX1RQLnByb3AiLCBncm91cHZhcnM9YygiU2l0ZS5HZW5vIiwgIlNpdGUiLCAiR2Vub3R5cGUiKSwgbmEucm09VFJVRSkNCg0KIyNQbG90IEF2ZXJhZ2UgUmV0ZW50aW9uIGFjcm9zcyBUcmVhdG1lbnRzDQpUb2xfU2NvcmVUUF9XMl9TRy5wbG90PC1nZ3Bsb3QoVG9sX1Njb3JlVFBfVzJfU0csIGFlcyh4PVNpdGUuR2VubywgeT1TY29yZV9UUC5wcm9wLCBjb2xvdXI9R2Vub3R5cGUpKSArIA0KICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluPVNjb3JlX1RQLnByb3Atc2UsIHltYXg9U2NvcmVfVFAucHJvcCtzZSksIHdpZHRoPWNhcC5zeiwgbGluZXdpZHRoPWJhci5zeikrDQogIGdlb21fcG9pbnQoc2l6ZT1wb2ludC5zeikrIA0KICAgZ2d0aXRsZSgiQ29sb3IgUmV0ZW50aW9uIGJ5IFRpbWVwb2ludCIpKw0KICB0aGVtZV9jbGFzc2ljKCkrDQogIHRoZW1lKCBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IGF4aXMudGl0bGUuc3opLCANCiAgICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIA0KICAgICAgICBheGlzLnRleHQueD1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLA0KICAgICAgICBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLCANCiAgICAgICAgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnR4dC5zeiksDQogICAgICAgIGxlZ2VuZC50aXRsZT1lbGVtZW50X3RleHQoc2l6ZT1sZWcudGl0bGUuc3opLCANCiAgICAgICAgbGVnZW5kLmJveC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGNvbG9yID0gImJsYWNrIiksDQogICAgICAgIGxlZ2VuZC5wb3NpdGlvbj0iYm90dG9tIiwgDQogICAgICAgIGxlZ2VuZC5kaXJlY3Rpb249Imhvcml6b250YWwiLA0KICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSBwbG90LnRpdGxlLnN6LCBjb2xvdXI9ImJsYWNrIiwgaGp1c3QgPSAwLjUpKSsNCiAgbGFicyh4PSIiLCB5PSJQcm9wb3J0aW9uIFJldGFpbmVkIikrDQogIHlsaW0oMCwgMS41KSsgDQogIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzPWMoIiIsIktsZWluIiwiIiwiIiwiU29tZXRoaW5nIFNwZWNpYWwiLCIiKSkrDQogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBHZW5vLmNvbG9ycy5vKSsgDQogIHN0YXRfcHZhbHVlX21hbnVhbChkYXRhPVRvbF9TY29yZVRQX1cyX2xtLnAsICB5LnBvc2l0aW9uPTEsIHN0ZXAuaW5jcmVhc2U9MC40NSwgbGFiZWw9IlNpZyIsIGhpZGUubnM9VFJVRSk7IFRvbF9TY29yZVRQX1cyX1NHLnBsb3QNCg0KYGBgDQoNCg0KIyMgQ29sb3IgU2NvcmUgYnkgVGltZXBvaW50IFN1bW1lciAyIFRpbWVwb2ludCBNMQ0KDQojIyMgUnVuIE1vZGVsDQpgYGB7cn0NCiMjQ2hlY2sgbm9ybWFsaXR5DQpoaXN0KFRvbERhdGFfTTEkU2NvcmVfVFAucHJvcCkNCnNoYXBpcm8udGVzdChUb2xEYXRhX00xJFNjb3JlX1RQLnByb3ApDQojTm90IG5vcm1hbA0KDQojI1RyeSBzcXVhcmUgdHJhbnNmb3JtYXRpb24NCmhpc3QoKFRvbERhdGFfTTEkU2NvcmVfVFAucHJvcCleMikNCnNoYXBpcm8udGVzdCgoVG9sRGF0YV9NMSRTY29yZV9UUC5wcm9wKV4yKQ0KI05vdCBub3JtYWwNCg0KIyNUcnkgY3ViZWQgdHJhbnNmb3JtYXRpb24NCmhpc3QoKFRvbERhdGFfTTEkU2NvcmVfVFAucHJvcCleMykNCnNoYXBpcm8udGVzdCgoVG9sRGF0YV9NMSRTY29yZV9UUC5wcm9wKV4zKQ0KI05vdCBub3JtYWwNCg0KIyNNb2RlbCBhcyBhIGZ1bmN0aW9uIG9mIFNpdGUgYW5kIEdlbm90eXBlDQojI01vZGVsIHdpdGggbm8gdHJhbnNmb3JtYXRpb24gYW5kIGNoZWNrIHJlc2lkdWFscw0KVG9sX1Njb3JlVFBfTTFfbG08LWxtKFNjb3JlX1RQLnByb3B+U2l0ZStHZW5vdHlwZStTaXRlOkdlbm90eXBlLCBkYXRhPVRvbERhdGFfTTEpDQoNCmBgYA0KDQoNCiMjIyMgQ2hlY2sgUmVzaWR1YWxzDQpgYGB7cn0NCiMjQ2hlY2sgTm9ybWFsaXR5IG9mIFJlc2lkdWFscw0KI0Rpc3RyaWJ1dGlvbiANCnBsb3QoZGVuc2l0eShyZXNpZChUb2xfU2NvcmVUUF9NMV9sbSkpKQ0KDQojUS1RIHBsb3QNCnFxbm9ybShyZXNpZChUb2xfU2NvcmVUUF9NMV9sbSkpOyBxcWxpbmUocmVzaWQoVG9sX1Njb3JlVFBfTTFfbG0pKQ0KDQojI0NoZWNrIFZhcmlhbmNlIG9mIFJlc2lkdWFscyBhY3Jvc3MgRml0dGVkIFZhbHVlcw0KcGxvdChmaXR0ZWQoVG9sX1Njb3JlVFBfTTFfbG0pLCByZXNpZChUb2xfU2NvcmVUUF9NMV9sbSkpDQoNCmBgYA0KDQoNCiMjIyBNb2RlbCBSZXN1bHRzDQoNCiMjIyMgT3ZlcmFsbA0KYGBge3J9DQojTW9kZWwgUmVzdWx0cw0Kc3VtbWFyeShUb2xfU2NvcmVUUF9NMV9sbSkNCmFub3ZhKFRvbF9TY29yZVRQX00xX2xtKQ0KDQojRWZmZWN0IFNpemUgb2YgUHJlZGljdG9ycw0KZXRhX3NxdWFyZWQoVG9sX1Njb3JlVFBfTTFfbG0sIHBhcnRpYWw9RkFMU0UpDQoNCiMjU2F2ZSBtb2RlbCByZXN1bHRzDQpUb2xfU2NvcmVUUF9NMV9sbS5yZXM8LWRhdGEuZnJhbWUoYW5vdmEoVG9sX1Njb3JlVFBfTTFfbG0pKQ0KVG9sX1Njb3JlVFBfTTFfbG0ucmVzJFByZWRpY3Rvcjwtcm93bmFtZXMoVG9sX1Njb3JlVFBfTTFfbG0ucmVzKQ0KVG9sX1Njb3JlVFBfTTFfbG0ucmVzJEV0YVNxPC1jKGV0YV9zcXVhcmVkKFRvbF9TY29yZVRQX00xX2xtLCBwYXJ0aWFsPUZBTFNFKSRFdGEyLCBOQSkNClRvbF9TY29yZVRQX00xX2xtLnJlcyRSZXNwb25zZTwtcmVwKCJDb2xvcl9UUCIsIG5yb3coVG9sX1Njb3JlVFBfTTFfbG0ucmVzKSkNClRvbF9TY29yZVRQX00xX2xtLnJlcyRUaW1lUDwtcmVwKCJNMSIsIG5yb3coVG9sX1Njb3JlVFBfTTFfbG0ucmVzKSkNClRvbF9TY29yZVRQX00xX2xtLnJlczwtVG9sX1Njb3JlVFBfTTFfbG0ucmVzICU+JSBkcGx5cjo6cmVuYW1lKCBwLnZhbHVlID0gIlByLi5GLiIsIERGPSAiRGYiKQ0KDQpgYGANCg0KU2lnbmlmaWNhbnQgZWZmZWN0IG9mIFNpdGUgYW5kIEdlbm90eXBlLiBTdGlsbCBjaGVja2luZyBTaXRlKkdlbm90eXBlIGZvciBjb21wYXJhYmlsaXR5IGFjcm9zcyBUaW1lcG9pbnRzLg0KDQoNCiMjIyMgUGFpcndpc2UNCmBgYHtyfQ0KI1BhaXJ3aXNlIGNvbXBhcmlzb25zIGFjcm9zczoNCg0KI0dlbm90eXBlcyB3aXRoaW4gU2l0ZXMNCmVtbWVhbnMoVG9sX1Njb3JlVFBfTTFfbG0sIHBhaXJ3aXNlfkdlbm90eXBlIHwgU2l0ZSkNCg0KI1NpdGVzIHdpdGhpbiBHZW5vdHlwZXMNCmVtbWVhbnMoVG9sX1Njb3JlVFBfTTFfbG0sIHBhaXJ3aXNlflNpdGUgfCBHZW5vdHlwZSkNCg0KIyNTYXZlIHAtdmFsdWVzDQoNCiNHZW5vdHlwZXMgd2l0aGluIFNpdGVzDQpUb2xfU2NvcmVUUF9NMV9sbS5nZW5vPC1kYXRhLmZyYW1lKGVtbWVhbnMoVG9sX1Njb3JlVFBfTTFfbG0sIHBhaXJ3aXNlfkdlbm90eXBlIHwgU2l0ZSkkY29udHJhc3RzKQ0KVG9sX1Njb3JlVFBfTTFfbG0uZ2VubzwtVG9sX1Njb3JlVFBfTTFfbG0uZ2VubyAlPiUgc2VwYXJhdGUoY29sPWNvbnRyYXN0LCBpbnRvPWMoImdyb3VwMSIsICJncm91cDIiKSwgc2VwPSIgLSAiLCByZW1vdmU9VFJVRSkNClRvbF9TY29yZVRQX00xX2xtLmdlbm8kZ3JvdXAxPC1wYXN0ZShUb2xfU2NvcmVUUF9NMV9sbS5nZW5vJFNpdGUsIFRvbF9TY29yZVRQX00xX2xtLmdlbm8kZ3JvdXAxLCBzZXA9Il8iKQ0KVG9sX1Njb3JlVFBfTTFfbG0uZ2VubyRncm91cDI8LXBhc3RlKFRvbF9TY29yZVRQX00xX2xtLmdlbm8kU2l0ZSwgVG9sX1Njb3JlVFBfTTFfbG0uZ2VubyRncm91cDIsIHNlcD0iXyIpDQoNCiNTaXRlcyB3aXRoaW4gR2Vub3R5cGVzDQpUb2xfU2NvcmVUUF9NMV9sbS5zaXRlPC1kYXRhLmZyYW1lKGVtbWVhbnMoVG9sX1Njb3JlVFBfTTFfbG0sIHBhaXJ3aXNlflNpdGUgfCBHZW5vdHlwZSkkY29udHJhc3RzKQ0KVG9sX1Njb3JlVFBfTTFfbG0uc2l0ZTwtVG9sX1Njb3JlVFBfTTFfbG0uc2l0ZSAlPiUgc2VwYXJhdGUoY29sPWNvbnRyYXN0LCBpbnRvPWMoImdyb3VwMSIsICJncm91cDIiKSwgc2VwPSIgLSAiLCByZW1vdmU9VFJVRSkNClRvbF9TY29yZVRQX00xX2xtLnNpdGUkZ3JvdXAxPC1wYXN0ZShUb2xfU2NvcmVUUF9NMV9sbS5zaXRlJGdyb3VwMSwgVG9sX1Njb3JlVFBfTTFfbG0uc2l0ZSRHZW5vdHlwZSwgc2VwPSJfIikNClRvbF9TY29yZVRQX00xX2xtLnNpdGUkZ3JvdXAyPC1wYXN0ZShUb2xfU2NvcmVUUF9NMV9sbS5zaXRlJGdyb3VwMiwgVG9sX1Njb3JlVFBfTTFfbG0uc2l0ZSRHZW5vdHlwZSwgc2VwPSJfIikNCg0KI0Z1bGwgbGlzdCBvZiBwLXZhbHVlcw0KVG9sX1Njb3JlVFBfTTFfbG0ucDwtcmJpbmQoVG9sX1Njb3JlVFBfTTFfbG0uZ2Vub1ssYygxOjIsNDo4KV0sIFRvbF9TY29yZVRQX00xX2xtLnNpdGVbLGMoMToyLDQ6OCldKQ0KVG9sX1Njb3JlVFBfTTFfbG0ucDwtVG9sX1Njb3JlVFBfTTFfbG0ucCAlPiUgZHBseXI6OnJlbmFtZSggcCA9IHAudmFsdWUpDQoNCiNBZGQgU2lnbmlmaWNhbmNlIExldmVscw0KVG9sX1Njb3JlVFBfTTFfbG0ucCRTaWc8LWlmZWxzZShUb2xfU2NvcmVUUF9NMV9sbS5wJHA8MC4wMDEsICIqKioiLCBpZmVsc2UoVG9sX1Njb3JlVFBfTTFfbG0ucCRwPDAuMDEsICIqKiIsIGlmZWxzZShUb2xfU2NvcmVUUF9NMV9sbS5wJHA8MC4wNSwgIioiLCBOQSkpKQ0KDQojU3BlY2lmeSBSZXNwb25zZSBhbmQgVGltZXBvaW50DQpUb2xfU2NvcmVUUF9NMV9sbS5wJFJlc3BvbnNlPC1yZXAoIkNvbG9yX1RQIiwgbnJvdyhUb2xfU2NvcmVUUF9NMV9sbS5wKSkNClRvbF9TY29yZVRQX00xX2xtLnAkVGltZVA8LXJlcCgiTTEiLCBucm93KFRvbF9TY29yZVRQX00xX2xtLnApKQ0KDQpgYGANCg0KDQojIyMgUGxvdCBSZXRlbnRpb24gYnkgU2l0ZSBhbmQgR2Vub3R5cGUNCmBgYHtyfQ0KIyNTdW1tYXJ5IHN0YXRpc3RpY3MgYnkgU2l0ZSBhbmQgR2Vub3R5cGUNClRvbF9TY29yZVRQX00xX1NHPC1zdW1tYXJ5U0UoVG9sRGF0YV9NMSwgbWVhc3VyZXZhcj0iU2NvcmVfVFAucHJvcCIsIGdyb3VwdmFycz1jKCJTaXRlLkdlbm8iLCAiU2l0ZSIsICJHZW5vdHlwZSIpLCBuYS5ybT1UUlVFKQ0KDQojI1Bsb3QgQXZlcmFnZSBSZXRlbnRpb24gYWNyb3NzIFRyZWF0bWVudHMNClRvbF9TY29yZVRQX00xX1NHLnBsb3Q8LWdncGxvdChUb2xfU2NvcmVUUF9NMV9TRywgYWVzKHg9U2l0ZS5HZW5vLCB5PVNjb3JlX1RQLnByb3AsIGNvbG91cj1HZW5vdHlwZSkpICsgDQogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49U2NvcmVfVFAucHJvcC1zZSwgeW1heD1TY29yZV9UUC5wcm9wK3NlKSwgd2lkdGg9Y2FwLnN6LCBsaW5ld2lkdGg9YmFyLnN6KSsNCiAgZ2VvbV9wb2ludChzaXplPXBvaW50LnN6KSsgDQogICBnZ3RpdGxlKCJDb2xvciBSZXRlbnRpb24gYnkgVGltZXBvaW50IikrDQogIHRoZW1lX2NsYXNzaWMoKSsNCiAgdGhlbWUoIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIA0KICAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSBheGlzLnRpdGxlLnN6KSwgDQogICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksDQogICAgICAgIGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksIA0KICAgICAgICBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoc2l6ZT1sZWcudHh0LnN6KSwNCiAgICAgICAgbGVnZW5kLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPWxlZy50aXRsZS5zeiksIA0KICAgICAgICBsZWdlbmQuYm94LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoY29sb3IgPSAiYmxhY2siKSwNCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJib3R0b20iLCANCiAgICAgICAgbGVnZW5kLmRpcmVjdGlvbj0iaG9yaXpvbnRhbCIsDQogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHBsb3QudGl0bGUuc3osIGNvbG91cj0iYmxhY2siLCBoanVzdCA9IDAuNSkpKw0KICBsYWJzKHg9IiIsIHk9IlByb3BvcnRpb24gUmV0YWluZWQiKSsNCiB5bGltKDAsIDEuNSkrIA0KICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscz1jKCIiLCJLbGVpbiIsIiIsIiIsIlNvbWV0aGluZyBTcGVjaWFsIiwiIikpKw0KICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gR2Vuby5jb2xvcnMubykrIA0KICBzdGF0X3B2YWx1ZV9tYW51YWwoZGF0YT1Ub2xfU2NvcmVUUF9NMV9sbS5wLCAgeS5wb3NpdGlvbj0xLjA1LCBzdGVwLmluY3JlYXNlPTAuMywgbGFiZWw9IlNpZyIsIGhpZGUubnM9VFJVRSk7IFRvbF9TY29yZVRQX00xX1NHLnBsb3QNCg0KYGBgDQoNCg0KIyMgQ29sb3IgU2NvcmUgYnkgVGltZXBvaW50IFdpbnRlciBUaW1lcG9pbnQgTTQNCg0KIyMjIFJ1biBNb2RlbA0KYGBge3J9DQojI0NoZWNrIG5vcm1hbGl0eQ0KaGlzdChUb2xEYXRhX000JFNjb3JlX1RQLnByb3ApDQpzaGFwaXJvLnRlc3QoVG9sRGF0YV9NNCRTY29yZV9UUC5wcm9wKQ0KI05vdCBOb3JtYWwNCg0KIyNUcnkgc3F1YXJlIHRyYW5zZm9ybWF0aW9uDQpoaXN0KChUb2xEYXRhX000JFNjb3JlX1RQLnByb3ApXjIpDQpzaGFwaXJvLnRlc3QoKFRvbERhdGFfTTQkU2NvcmVfVFAucHJvcCleMikNCiNOb3QgTm9ybWFsDQoNCiMjVHJ5IGN1YmVkIHRyYW5zZm9ybWF0aW9uDQpoaXN0KChUb2xEYXRhX000JFNjb3JlX1RQLnByb3ApXjMpDQpzaGFwaXJvLnRlc3QoKFRvbERhdGFfTTQkU2NvcmVfVFAucHJvcCleMykNCiNOb3QgTm9ybWFsDQoNCiMjTW9kZWwgYXMgYSBmdW5jdGlvbiBvZiBTaXRlIGFuZCBHZW5vdHlwZQ0KIyNNb2RlbCB3aXRoIG5vIHRyYW5zZm9ybWF0aW9uIGFuZCBjaGVjayByZXNpZHVhbHMNClRvbF9TY29yZVRQX000X2xtPC1sbShTY29yZV9UUC5wcm9wflNpdGUrR2Vub3R5cGUrU2l0ZTpHZW5vdHlwZSwgZGF0YT1Ub2xEYXRhX000KQ0KDQpgYGANCg0KDQojIyMjIENoZWNrIFJlc2lkdWFscw0KYGBge3J9DQojI0NoZWNrIE5vcm1hbGl0eSBvZiBSZXNpZHVhbHMNCiNEaXN0cmlidXRpb24gDQpwbG90KGRlbnNpdHkocmVzaWQoVG9sX1Njb3JlVFBfTTRfbG0pKSkNCg0KI1EtUSBwbG90DQpxcW5vcm0ocmVzaWQoVG9sX1Njb3JlVFBfTTRfbG0pKTsgcXFsaW5lKHJlc2lkKFRvbF9TY29yZVRQX000X2xtKSkNCg0KIyNDaGVjayBWYXJpYW5jZSBvZiBSZXNpZHVhbHMgYWNyb3NzIEZpdHRlZCBWYWx1ZXMNCnBsb3QoZml0dGVkKFRvbF9TY29yZVRQX000X2xtKSwgcmVzaWQoVG9sX1Njb3JlVFBfTTRfbG0pKQ0KDQpgYGANCg0KDQojIyMgTW9kZWwgUmVzdWx0cw0KDQojIyMjIE92ZXJhbGwNCmBgYHtyfQ0KI01vZGVsIFJlc3VsdHMNCnN1bW1hcnkoVG9sX1Njb3JlVFBfTTRfbG0pDQphbm92YShUb2xfU2NvcmVUUF9NNF9sbSkNCg0KI0VmZmVjdCBTaXplIG9mIFByZWRpY3RvcnMNCmV0YV9zcXVhcmVkKFRvbF9TY29yZVRQX000X2xtLCBwYXJ0aWFsPUZBTFNFKQ0KDQojI1NhdmUgbW9kZWwgcmVzdWx0cw0KVG9sX1Njb3JlVFBfTTRfbG0ucmVzPC1kYXRhLmZyYW1lKGFub3ZhKFRvbF9TY29yZVRQX000X2xtKSkNClRvbF9TY29yZVRQX000X2xtLnJlcyRQcmVkaWN0b3I8LXJvd25hbWVzKFRvbF9TY29yZVRQX000X2xtLnJlcykNClRvbF9TY29yZVRQX000X2xtLnJlcyRFdGFTcTwtYyhldGFfc3F1YXJlZChUb2xfU2NvcmVUUF9NNF9sbSwgcGFydGlhbD1GQUxTRSkkRXRhMiwgTkEpDQpUb2xfU2NvcmVUUF9NNF9sbS5yZXMkUmVzcG9uc2U8LXJlcCgiQ29sb3JfVFAiLCBucm93KFRvbF9TY29yZVRQX000X2xtLnJlcykpDQpUb2xfU2NvcmVUUF9NNF9sbS5yZXMkVGltZVA8LXJlcCgiTTQiLCBucm93KFRvbF9TY29yZVRQX000X2xtLnJlcykpDQpUb2xfU2NvcmVUUF9NNF9sbS5yZXM8LVRvbF9TY29yZVRQX000X2xtLnJlcyAlPiUgZHBseXI6OnJlbmFtZSggcC52YWx1ZSA9ICJQci4uRi4iLCBERj0gIkRmIikNCg0KYGBgDQoNClNpZ25pZmljYW50IGVmZmVjdCBvZiBHZW5vdHlwZS4gU3RpbGwgY2hlY2tpbmcgU2l0ZSpHZW5vdHlwZSBmb3IgY29tcGFyYWJpbGl0eSBhY3Jvc3MgVGltZXBvaW50cy4NCg0KDQoNCiMjIyMgUGFpcndpc2UNCmBgYHtyfQ0KI1BhaXJ3aXNlIGNvbXBhcmlzb25zIGFjcm9zczoNCg0KI0dlbm90eXBlcyB3aXRoaW4gU2l0ZXMNCmVtbWVhbnMoVG9sX1Njb3JlVFBfTTRfbG0sIHBhaXJ3aXNlfkdlbm90eXBlIHwgU2l0ZSkNCg0KI1NpdGVzIHdpdGhpbiBHZW5vdHlwZXMNCmVtbWVhbnMoVG9sX1Njb3JlVFBfTTRfbG0sIHBhaXJ3aXNlflNpdGUgfCBHZW5vdHlwZSkNCg0KIyNTYXZlIHAtdmFsdWVzDQoNCiNHZW5vdHlwZXMgd2l0aGluIFNpdGVzDQpUb2xfU2NvcmVUUF9NNF9sbS5nZW5vPC1kYXRhLmZyYW1lKGVtbWVhbnMoVG9sX1Njb3JlVFBfTTRfbG0sIHBhaXJ3aXNlfkdlbm90eXBlIHwgU2l0ZSkkY29udHJhc3RzKQ0KVG9sX1Njb3JlVFBfTTRfbG0uZ2VubzwtVG9sX1Njb3JlVFBfTTRfbG0uZ2VubyAlPiUgc2VwYXJhdGUoY29sPWNvbnRyYXN0LCBpbnRvPWMoImdyb3VwMSIsICJncm91cDIiKSwgc2VwPSIgLSAiLCByZW1vdmU9VFJVRSkNClRvbF9TY29yZVRQX000X2xtLmdlbm8kZ3JvdXAxPC1wYXN0ZShUb2xfU2NvcmVUUF9NNF9sbS5nZW5vJFNpdGUsIFRvbF9TY29yZVRQX000X2xtLmdlbm8kZ3JvdXAxLCBzZXA9Il8iKQ0KVG9sX1Njb3JlVFBfTTRfbG0uZ2VubyRncm91cDI8LXBhc3RlKFRvbF9TY29yZVRQX000X2xtLmdlbm8kU2l0ZSwgVG9sX1Njb3JlVFBfTTRfbG0uZ2VubyRncm91cDIsIHNlcD0iXyIpDQoNCiNTaXRlcyB3aXRoaW4gR2Vub3R5cGVzDQpUb2xfU2NvcmVUUF9NNF9sbS5zaXRlPC1kYXRhLmZyYW1lKGVtbWVhbnMoVG9sX1Njb3JlVFBfTTRfbG0sIHBhaXJ3aXNlflNpdGUgfCBHZW5vdHlwZSkkY29udHJhc3RzKQ0KVG9sX1Njb3JlVFBfTTRfbG0uc2l0ZTwtVG9sX1Njb3JlVFBfTTRfbG0uc2l0ZSAlPiUgc2VwYXJhdGUoY29sPWNvbnRyYXN0LCBpbnRvPWMoImdyb3VwMSIsICJncm91cDIiKSwgc2VwPSIgLSAiLCByZW1vdmU9VFJVRSkNClRvbF9TY29yZVRQX000X2xtLnNpdGUkZ3JvdXAxPC1wYXN0ZShUb2xfU2NvcmVUUF9NNF9sbS5zaXRlJGdyb3VwMSwgVG9sX1Njb3JlVFBfTTRfbG0uc2l0ZSRHZW5vdHlwZSwgc2VwPSJfIikNClRvbF9TY29yZVRQX000X2xtLnNpdGUkZ3JvdXAyPC1wYXN0ZShUb2xfU2NvcmVUUF9NNF9sbS5zaXRlJGdyb3VwMiwgVG9sX1Njb3JlVFBfTTRfbG0uc2l0ZSRHZW5vdHlwZSwgc2VwPSJfIikNCg0KI0Z1bGwgbGlzdCBvZiBwLXZhbHVlcw0KVG9sX1Njb3JlVFBfTTRfbG0ucDwtcmJpbmQoVG9sX1Njb3JlVFBfTTRfbG0uZ2Vub1ssYygxOjIsNDo4KV0sIFRvbF9TY29yZVRQX000X2xtLnNpdGVbLGMoMToyLDQ6OCldKQ0KVG9sX1Njb3JlVFBfTTRfbG0ucDwtVG9sX1Njb3JlVFBfTTRfbG0ucCAlPiUgZHBseXI6OnJlbmFtZSggcCA9IHAudmFsdWUpDQoNCiNBZGQgU2lnbmlmaWNhbmNlIExldmVscw0KVG9sX1Njb3JlVFBfTTRfbG0ucCRTaWc8LWlmZWxzZShUb2xfU2NvcmVUUF9NNF9sbS5wJHA8MC4wMDEsICIqKioiLCBpZmVsc2UoVG9sX1Njb3JlVFBfTTRfbG0ucCRwPDAuMDEsICIqKiIsIGlmZWxzZShUb2xfU2NvcmVUUF9NNF9sbS5wJHA8MC4wNSwgIioiLCBOQSkpKQ0KDQojU3BlY2lmeSBSZXNwb25zZSBhbmQgVGltZXBvaW50DQpUb2xfU2NvcmVUUF9NNF9sbS5wJFJlc3BvbnNlPC1yZXAoIkNvbG9yX1RQIiwgbnJvdyhUb2xfU2NvcmVUUF9NNF9sbS5wKSkNClRvbF9TY29yZVRQX000X2xtLnAkVGltZVA8LXJlcCgiTTQiLCBucm93KFRvbF9TY29yZVRQX000X2xtLnApKQ0KDQpgYGANCg0KDQojIyMgUGxvdCBSZXRlbnRpb24gYnkgU2l0ZSBhbmQgR2Vub3R5cGUNCmBgYHtyfQ0KIyNTdW1tYXJ5IHN0YXRpc3RpY3MgYnkgU2l0ZSBhbmQgR2Vub3R5cGUNClRvbF9TY29yZVRQX000X1NHPC1zdW1tYXJ5U0UoVG9sRGF0YV9NNCwgbWVhc3VyZXZhcj0iU2NvcmVfVFAucHJvcCIsIGdyb3VwdmFycz1jKCJTaXRlLkdlbm8iLCAiU2l0ZSIsICJHZW5vdHlwZSIpLCBuYS5ybT1UUlVFKQ0KDQojI1Bsb3QgQXZlcmFnZSBSZXRlbnRpb24gYWNyb3NzIFRyZWF0bWVudHMNClRvbF9TY29yZVRQX000X1NHLnBsb3Q8LWdncGxvdChUb2xfU2NvcmVUUF9NNF9TRywgYWVzKHg9U2l0ZS5HZW5vLCB5PVNjb3JlX1RQLnByb3AsIGNvbG91cj1HZW5vdHlwZSkpICsgDQogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49U2NvcmVfVFAucHJvcC1zZSwgeW1heD1TY29yZV9UUC5wcm9wK3NlKSwgd2lkdGg9Y2FwLnN6LCBsaW5ld2lkdGg9YmFyLnN6KSsNCiAgZ2VvbV9wb2ludChzaXplPXBvaW50LnN6KSsgDQogICBnZ3RpdGxlKCJDb2xvciBSZXRlbnRpb24gYnkgVGltZXBvaW50IikrDQogIHRoZW1lX2NsYXNzaWMoKSsNCiAgdGhlbWUoIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIA0KICAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSBheGlzLnRpdGxlLnN6KSwgDQogICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksDQogICAgICAgIGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksIA0KICAgICAgICBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoc2l6ZT1sZWcudHh0LnN6KSwNCiAgICAgICAgbGVnZW5kLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPWxlZy50aXRsZS5zeiksIA0KICAgICAgICBsZWdlbmQuYm94LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoY29sb3IgPSAiYmxhY2siKSwNCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJib3R0b20iLCANCiAgICAgICAgbGVnZW5kLmRpcmVjdGlvbj0iaG9yaXpvbnRhbCIsDQogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHBsb3QudGl0bGUuc3osIGNvbG91cj0iYmxhY2siLCBoanVzdCA9IDAuNSkpKw0KICBsYWJzKHg9IiIsIHk9IlByb3BvcnRpb24gUmV0YWluZWQiKSsNCiAgeWxpbSgwLCAxLjUpKyANCiAgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHM9YygiIiwiS2xlaW4iLCIiLCIiLCJTb21ldGhpbmcgU3BlY2lhbCIsIiIpKSsNCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IEdlbm8uY29sb3JzLm8pKyANCiAgc3RhdF9wdmFsdWVfbWFudWFsKGRhdGE9VG9sX1Njb3JlVFBfTTRfbG0ucCwgIHkucG9zaXRpb249MS4xLCBzdGVwLmluY3JlYXNlPTAuNCwgbGFiZWw9IlNpZyIsIGhpZGUubnM9VFJVRSk7IFRvbF9TY29yZVRQX000X1NHLnBsb3QNCg0KYGBgDQoNCg0KIyBDb250cmFzdHMgQWNyb3NzIE1ldHJpY3MNCg0KIyMjIENvbWJpbmUgQ29udHJhc3QgUmVzdWx0cw0KQ3JlYXRpbmcgYSBoZWF0bWFwIHRvIGNvbXBhcmUgdGhlIGRpcmVjdGlvbiBhbmQgc2lnbmlmaWNhbmNlIG9mIHBhaXJ3aXNlIGNvbXBhcmlzb25zIGFjcm9zcyBUb2xlcmFuY2UgbWV0cmljcy4gUG9zaXRpdmUgZXN0aW1hdGVzIGluZGljYXRlIHRoYXQgR3JvdXAgMSA+IEdyb3VwIDIuIFAgdmFsdWVzIG9mIGxlc3MgdGhhbiAwLjA1IGFyZSBjb25zaWRlcmVkIHNpZ25pZmljYW50LiAgIA0KYGBge3J9DQojI0NvbWJpbmUgUmVzdWx0cw0KVG9sX2NvbnRyYXN0czwtcmJpbmQoVG9sX0NobF9XMl9sbS5wLCBUb2xfQ2hsX00xX2xtLnAsIFRvbF9DaGxfTTRfbG0ucCwgDQogICAgICAgICAgICAgICAgICAgICBUb2xfU3ltX1cyX2xtLnAsIFRvbF9TeW1fTTFfbG0ucCwgVG9sX1N5bV9NNF9sbS5wLCANCiAgICAgICAgICAgICAgICAgICAgIFRvbF9TY29yZUZfVzJfbG0ucCwgVG9sX1Njb3JlRl9NMV9sbS5wLCBUb2xfU2NvcmVGX000X2xtLnAsIA0KICAgICAgICAgICAgICAgICAgICAgVG9sX1Njb3JlVFBfVzJfbG0ucCwgVG9sX1Njb3JlVFBfTTFfbG0ucCwgVG9sX1Njb3JlVFBfTTRfbG0ucCkNCg0KIyNDcmVhdGUgQ29udHJhc3QgQ29sdW1uDQpUb2xfY29udHJhc3RzJENvbnRyYXN0PC1wYXN0ZShUb2xfY29udHJhc3RzJGdyb3VwMSwgVG9sX2NvbnRyYXN0cyRncm91cDIsIHNlcD0iIHYuICIpDQoNCiMjQWRkIFNldCBjb2x1bW4gd2l0aCBDb250cmFzdCBhbmQgVGltZXBvaW50DQpUb2xfY29udHJhc3RzJFNldDwtcGFzdGUoVG9sX2NvbnRyYXN0cyRUaW1lUCwgVG9sX2NvbnRyYXN0cyRDb250cmFzdCwgc2VwPSIgIikNCg0KIyNSZS1vcmRlciBieSBTZWFzb25hbCBUaW1lcG9pbnQNClRvbF9jb250cmFzdHMkVGltZVA8LWZhY3RvcihUb2xfY29udHJhc3RzJFRpbWVQLCBsZXZlbHM9YygiVzIiLCAiTTEiLCAiTTQiKSwgb3JkZXJlZD1UUlVFKQ0KVG9sX2NvbnRyYXN0czwtIFRvbF9jb250cmFzdHMgJT4lIGFycmFuZ2UoZGVzYyhhcy5udW1lcmljKFRpbWVQKSkpDQoNClRvbF9jb250cmFzdHMkU2V0PC1mYWN0b3IoVG9sX2NvbnRyYXN0cyRTZXQsIGxldmVscz1jKHVuaXF1ZShUb2xfY29udHJhc3RzJFNldCkpLCBvcmRlcmVkPVRSVUUpDQpgYGANCg0KDQojIyMgU3RhbmRhcmRpemUgUmVzcG9uc2UgU2NhbGUNCkNvbnZlcnQgRXN0aW1hdGUgdG8gdGhlIFJlc3BvbnNlIHNjYWxlIChpbnN0ZWFkIG9mIGxvZyArMSBzY2FsZSkgZm9yIG1vZGVscyB3aGVyZSB0aGUgcmVzcG9uc2Ugd2FzIGxvZyB0cmFuc2Zvcm1lZA0KYGBge3J9DQpUb2xfY29udHJhc3RzJEVzdGltYXRlPC1Ub2xfY29udHJhc3RzJGVzdGltYXRlDQoNCiNDaGwgTTQNClRvbF9jb250cmFzdHMkRXN0aW1hdGVbd2hpY2goVG9sX2NvbnRyYXN0cyRSZXNwb25zZT09IkNobG9yb3BoeWxsIiAmIFRvbF9jb250cmFzdHMkVGltZVA9PSJNNCIpXTwtYyhleHAoVG9sX2NvbnRyYXN0cyRlc3RpbWF0ZVt3aGljaChUb2xfY29udHJhc3RzJFJlc3BvbnNlPT0iQ2hsb3JvcGh5bGwiICYgVG9sX2NvbnRyYXN0cyRUaW1lUD09Ik00IildKS0xKQ0KDQojU3ltIE0xDQpUb2xfY29udHJhc3RzJEVzdGltYXRlW3doaWNoKFRvbF9jb250cmFzdHMkUmVzcG9uc2U9PSJTeW1iaW9udHMiICYgVG9sX2NvbnRyYXN0cyRUaW1lUD09Ik0xIildPC1jKGV4cChUb2xfY29udHJhc3RzJGVzdGltYXRlW3doaWNoKFRvbF9jb250cmFzdHMkUmVzcG9uc2U9PSJTeW1iaW9udHMiICYgVG9sX2NvbnRyYXN0cyRUaW1lUD09Ik0xIildKS0xKQ0KDQoNCmBgYA0KDQoNCiMjIENvbnRyYXN0IEhlYXRtYXBzDQoNCiMjIyMgU3VtbWVyIDEgVGltZXBvaW50IFcyDQpgYGB7cn0NClRvbF9QYWlyc19XMi5wbG90PC1nZ3Bsb3QoZGF0YT1Ub2xfY29udHJhc3RzW3doaWNoKFRvbF9jb250cmFzdHMkVGltZVA9PSJXMiIpLF0sIGFlcyh4PVJlc3BvbnNlLCB5PUNvbnRyYXN0LCBmaWxsPUVzdGltYXRlKSkrDQogIGdlb21fdGlsZSgpKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsPVNpZyksIHNpemU9c2lnLnN6KSsNCiAgc2NhbGVfZmlsbF9ncmFkaWVudDIobG93PSIjQkExRTAyRkYiLCBtaWQ9IndoaXRlIiwgaGlnaD0iIzNCQTBGREZGIikrDQogIHRoZW1lX2J3KCkrDQogIGdndGl0bGUoIlBhaXJ3aXNlIENvbnRyYXN0cyBTdW1tZXIgMSIpKw0KICB0aGVtZShheGlzLnRleHQueD1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnRpdGxlLnN6LCBjb2xvdXI9ImJsYWNrIiwgYW5nbGU9NDUsIGhqdXN0PTEpLA0KICAgICAgICBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zei0xLCBjb2xvdXI9ImJsYWNrIiksDQogICAgICAgIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPWxlZy50eHQuc3opLA0KICAgICAgICBsZWdlbmQudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnRpdGxlLnN6KSwgDQogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHBsb3QudGl0bGUuc3osIGNvbG91cj0iYmxhY2siLCBoanVzdCA9IDAuNSkpKw0KICBsYWJzKHg9IiIsIHk9IiIsIGZpbGw9IkVzdGltYXRlIik7VG9sX1BhaXJzX1cyLnBsb3QNCmBgYA0KDQoNCiMjIyMgU3VtbWVyIDIgVGltZXBvaW50IE0xDQpgYGB7cn0NClRvbF9QYWlyc19NMS5wbG90PC1nZ3Bsb3QoZGF0YT1Ub2xfY29udHJhc3RzW3doaWNoKFRvbF9jb250cmFzdHMkVGltZVA9PSJNMSIpLF0sIGFlcyh4PVJlc3BvbnNlLCB5PUNvbnRyYXN0LCBmaWxsPUVzdGltYXRlKSkrDQogIGdlb21fdGlsZSgpKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsPVNpZyksIHNpemU9c2lnLnN6KSsNCiAgc2NhbGVfZmlsbF9ncmFkaWVudDIobG93PSIjQkExRTAyRkYiLCBtaWQ9IndoaXRlIiwgaGlnaD0iIzNCQTBGREZGIikrDQogIHRoZW1lX2J3KCkrDQogIGdndGl0bGUoIlBhaXJ3aXNlIENvbnRyYXN0cyBTdW1tZXIgMiIpKw0KICB0aGVtZShheGlzLnRleHQueD1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnRpdGxlLnN6LCBjb2xvdXI9ImJsYWNrIiwgYW5nbGU9NDUsIGhqdXN0PTEpLA0KICAgICAgICBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zei0xLCBjb2xvdXI9ImJsYWNrIiksDQogICAgICAgIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPWxlZy50eHQuc3opLA0KICAgICAgICBsZWdlbmQudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnRpdGxlLnN6KSwgDQogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHBsb3QudGl0bGUuc3osIGNvbG91cj0iYmxhY2siLCBoanVzdCA9IDAuNSkpKw0KICBsYWJzKHg9IiIsIHk9IiIsIGZpbGw9IkVzdGltYXRlIik7VG9sX1BhaXJzX00xLnBsb3QNCmBgYA0KDQoNCiMjIyMgV2ludGVyIFRpbWVwb2ludCBNNA0KYGBge3J9DQpUb2xfUGFpcnNfTTQucGxvdDwtZ2dwbG90KGRhdGE9VG9sX2NvbnRyYXN0c1t3aGljaChUb2xfY29udHJhc3RzJFRpbWVQPT0iTTQiKSxdLCBhZXMoeD1SZXNwb25zZSwgeT1Db250cmFzdCwgZmlsbD1Fc3RpbWF0ZSkpKw0KICBnZW9tX3RpbGUoKSsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1TaWcpLCBzaXplPXNpZy5zeikrDQogIHNjYWxlX2ZpbGxfZ3JhZGllbnQyKGxvdz0iI0JBMUUwMkZGIiwgbWlkPSJ3aGl0ZSIsIGhpZ2g9IiMzQkEwRkRGRiIpKw0KICB0aGVtZV9idygpKw0KICBnZ3RpdGxlKCJQYWlyd2lzZSBDb250cmFzdHMgTW9udGggNCIpKw0KICB0aGVtZShheGlzLnRleHQueD1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnRpdGxlLnN6LCBjb2xvdXI9ImJsYWNrIiwgYW5nbGU9NDUsIGhqdXN0PTEpLA0KICAgICAgICBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zei0xLCBjb2xvdXI9ImJsYWNrIiksDQogICAgICAgIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPWxlZy50eHQuc3opLA0KICAgICAgICBsZWdlbmQudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnRpdGxlLnN6KSwgDQogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHBsb3QudGl0bGUuc3osIGNvbG91cj0iYmxhY2siLCBoanVzdCA9IDAuNSkpKw0KICBsYWJzKHg9IiIsIHk9IiIsIGZpbGw9IkVzdGltYXRlIik7VG9sX1BhaXJzX000LnBsb3QNCmBgYA0KDQoNCiMjIyMgQWxsIFRpbWVwb2ludHMNCmBgYHtyfQ0KVG9sX1BhaXJzLnBsb3Q8LWdncGxvdChkYXRhPVRvbF9jb250cmFzdHMsIGFlcyh4PVJlc3BvbnNlLCB5PVNldCwgZmlsbD1Fc3RpbWF0ZSkpKw0KICBnZW9tX3RpbGUoKSsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1TaWcpLCBzaXplPXNpZy5zeikrDQogIHNjYWxlX2ZpbGxfZ3JhZGllbnQyKGxvdz0iI0JBMUUwMkZGIiwgbWlkPSJ3aGl0ZSIsIGhpZ2g9IiMzQkEwRkRGRiIpKw0KICB0aGVtZV9idygpKw0KICBnZ3RpdGxlKCJQYWlyd2lzZSBDb250cmFzdHMiKSsNCiAgdGhlbWUoYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50aXRsZS5zeiwgY29sb3VyPSJibGFjayIsIGFuZ2xlPTQ1LCBoanVzdD0xKSwNCiAgICAgICAgYXhpcy50ZXh0Lnk9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50eHQuc3otMSwgY29sb3VyPSJibGFjayIpLA0KICAgICAgICBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoc2l6ZT1sZWcudHh0LnN6KSwNCiAgICAgICAgbGVnZW5kLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPWxlZy50aXRsZS5zeiksIA0KICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSBwbG90LnRpdGxlLnN6LCBjb2xvdXI9ImJsYWNrIiwgaGp1c3QgPSAwLjUpKSsNCiAgbGFicyh4PSIiLCB5PSIiLCBmaWxsPSJFc3RpbWF0ZSIpO1RvbF9QYWlycy5wbG90DQpgYGANCg0KDQojIyMjIFNpZ25pZmljYW50IERpZmZlcmVuY2VzDQoNClN1YnNldHRpbmcgQ29udHJhc3RzIHRvIG9ubHkgaW5jbHVkZSBjb250cmFzdHMgd2l0aCBzaWduaWZpY2FudCBkaWZmZXJlbmNlcyBpbiBhdCBsZWFzdCBvbmUgb2YgdGhlIHRoZXJtYWwgdG9sZXJhbmNlIG1ldHJpY3MgKENobG9yb3BoeWxsIG9yIFN5bWJpb250IG9yIENvbG9yIHJldGVudGlvbikNCmBgYHtyfQ0KIyNSZW1vdmUgcm93cyB3aXRoIG5vbi1zaWduaWZpY2FudCBwLXZhbHVlcw0KVG9sX2NvbnRyYXN0c19zaWc8LXN1YnNldChUb2xfY29udHJhc3RzLCBwIDwgMC4wNSkNCg0KIyNLZWVwIFNldHMgd2hlcmUgYXQgbGVhc3Qgb25lIG1ldHJpYyBzaG93cyBhIHNpZ25pZmljYW50IGRpZmZlcmVuY2UNClRvbF9TZXRzX3NpZzwtZGF0YS5mcmFtZShTZXQ9Yyh1bmlxdWUoVG9sX2NvbnRyYXN0c19zaWckU2V0KSkpDQpUb2xfY29udHJhc3RzX3NpZ19TZXQ8LW1lcmdlKFRvbF9TZXRzX3NpZywgVG9sX2NvbnRyYXN0cywgYWxsLng9VFJVRSwgYWxsLnk9RkFMU0UpDQoNCmBgYA0KDQoNCmBgYHtyfQ0KVG9sX1BhaXJzX3NpZy5wbG90PC1nZ3Bsb3QoZGF0YT1Ub2xfY29udHJhc3RzX3NpZ19TZXQsIGFlcyh4PVJlc3BvbnNlLCB5PVNldCwgZmlsbD1Fc3RpbWF0ZSkpKw0KICBnZW9tX3RpbGUoKSsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1TaWcpLCBzaXplPXNpZy5zeikrDQogIHNjYWxlX2ZpbGxfZ3JhZGllbnQyKGxvdz0iI0JBMUUwMkZGIiwgbWlkPSJ3aGl0ZSIsIGhpZ2g9IiMzQkEwRkRGRiIpKw0KICB0aGVtZV9idygpKw0KICBnZ3RpdGxlKCJTaWduaWZpY2FudCBQYWlyd2lzZSBDb250cmFzdHMiKSsNCiAgdGhlbWUoYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50aXRsZS5zeiwgY29sb3VyPSJibGFjayIsIGFuZ2xlPTQ1LCBoanVzdD0xKSwNCiAgICAgICAgYXhpcy50ZXh0Lnk9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50eHQuc3otMSwgY29sb3VyPSJibGFjayIpLA0KICAgICAgICBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoc2l6ZT1sZWcudHh0LnN6KSwNCiAgICAgICAgbGVnZW5kLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPWxlZy50aXRsZS5zeiksIA0KICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSBwbG90LnRpdGxlLnN6LCBjb2xvdXI9ImJsYWNrIiwgaGp1c3QgPSAwLjUpKSsNCiAgbGFicyh4PSIiLCB5PSIiLCBmaWxsPSJFc3RpbWF0ZSIpO1RvbF9QYWlyc19zaWcucGxvdA0KYGBgDQoNCg0KIyMjIFByb3BvcnRpb24gb2YgQWdyZWVtZW50DQpBc3Nlc3NpbmcgdGhlIHByb3BvcnRpb24gb2YgYWdyZWVtZW50IGJldHdlZW4gbWV0aG9kcyBhcyB0aGUgcGFpcndpc2UgY29tcGFyaXNvbnMgd2hlcmUgdHdvIG1ldGhvZHMgYm90aCBmaW5kIGEgc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSBvdXQgb2YgdGhlIHRvdGFsIHBhaXJ3aXNlIGNvbXBhcmlzb25zLiBDYWxjdWxhdGluZyB0aGUgcHJvcG9ydGlvbiBvZiBhZ3JlZW1lbnQgYmV0d2VlbiBDaGxvcm9waHlsbCBhbmQgQ29sb3IgRnVsbCBTZXQsIENobG9yb3BoeWxsIGFuZCBDb2xvciBUaW1lcG9pbnQsIFN5bWJpb250cyBhbmQgQ29sb3IgRnVsbCBTZXQsIFN5bWJpb250cyBhbmQgQ29sb3IgVGltZXBvaW50LCBhbmQgQ2hsb3JvcGh5bGwgYW5kIFN5bWJpb250cy4gQ29tcGFyaW5nIHRoZSBwcm9wb3J0aW9uIG9mIGFncmVlbWVudCBiZXR3ZWVuIG1ldGhvZHMgb2YgcXVhbnRpZnlpbmcgdGhlcm1hbCB0b2xlcmFuY2UuDQpgYGB7cn0NCm5hbWVzKFRvbF9jb250cmFzdHMpDQoNCiMjQ2hhbmdlIGxvbmcgdG8gc2hvcnQgZm9ybWF0DQpUb2xfY29udHJhc3RzLmFncmVlPC1Ub2xfY29udHJhc3RzICU+JSBwaXZvdF93aWRlcihuYW1lc19mcm9tPSJSZXNwb25zZSIsIHZhbHVlc19mcm9tPWMoInAiLCAiRXN0aW1hdGUiKSwgaWRfY29scz1jKCJUaW1lUCIsICJDb250cmFzdCIsICJTZXQiKSkNCg0KIyNDb252ZXJ0IHAgdmFsdWVzIHRvIGJpbmFyeQ0KIzA6IE5vIHNpZ25pZmljYW50IGRpZmZlcmVuY2UgKHA+MC4wNSkgZGV0ZWN0ZWQgaW4gdGhhdCBwYWlyd2lzZSBjb250cmFzdA0KIzE6IFNpZ25pZmljYW50IGRpZmZlcmVuY2UgKHA8MC4wNSkgZGV0ZWN0ZWQgaW4gdGhhdCBwYWlyd2lzZSBjb250cmFzdA0KVG9sX2NvbnRyYXN0cy5hZ3JlZVssYyg0OjcpXTwtaWZlbHNlKFRvbF9jb250cmFzdHMuYWdyZWVbLGMoNDo3KV08MC4wNSwgMSwgMCkNCg0KIyNDb252ZXJ0IGVzdGltYXRlcyB0byBHcmVhdGVyIG9yIExlc3MNCiNHcmVhdGVyOiBQb3NpdGl2ZSBlc3RpbWF0ZXMgaW5kaWNhdGUgQT5CIGluIHRoZSBDb250cmFzdA0KI0xlc3M6IE5lZ2F0aXZlIGVzdGltYXRlcyBpbmRpY2F0ZSBBPEIgaW4gdGhlIENvbnRyYXN0DQpUb2xfY29udHJhc3RzLmFncmVlWyxjKDg6MTEpXTwtaWZlbHNlKFRvbF9jb250cmFzdHMuYWdyZWVbLGMoODoxMSldPDAsICJMZXNzIiwgIkdyZWF0ZXIiKQ0KDQojI0lkZW50aWZ5IGFncmVlbWVudA0KIzE6IEJvdGggbWV0cmljcyBpZGVudGlmaWVkIGEgc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSBpbiB0aGF0IHBhaXJ3aXNlIGNvbnRyYXN0IE9SIE5laXRoZXIgbWV0cmljIGlkZW50aWZpZWQgYSBzaWduaWZpY2FudCBkaWZmZXJlbmNlDQojMDogT25lIG1ldHJpY3MgaWRlbnRpZmllZCBhIHNpZ25pZmljYW50IGRpZmZlcmVuY2UgaW4gdGhhdCBwYWlyd2lzZSBjb250cmFzdA0KI0ZvciBlYWNoIG1hdGNoaW5nIGNhc2UgKDEpLCBjb25maXJtIG1hdGNoaW5nIEVzdGltYXRlcw0KVG9sX2NvbnRyYXN0cy5hZ3JlZSRDaGwuU3ltPC1pZmVsc2UoVG9sX2NvbnRyYXN0cy5hZ3JlZSRwX0NobG9yb3BoeWxsPT0xICYNClRvbF9jb250cmFzdHMuYWdyZWUkcF9DaGxvcm9waHlsbD09VG9sX2NvbnRyYXN0cy5hZ3JlZSRwX1N5bWJpb250cyAmDQpUb2xfY29udHJhc3RzLmFncmVlJEVzdGltYXRlX0NobG9yb3BoeWxsPT1Ub2xfY29udHJhc3RzLmFncmVlJEVzdGltYXRlX1N5bWJpb250cywgMSwgDQppZmVsc2UoVG9sX2NvbnRyYXN0cy5hZ3JlZSRwX0NobG9yb3BoeWxsPT0wICYgDQogICAgICAgICBUb2xfY29udHJhc3RzLmFncmVlJHBfQ2hsb3JvcGh5bGw9PVRvbF9jb250cmFzdHMuYWdyZWUkcF9TeW1iaW9udHMsIDEsIDApKQ0KDQpUb2xfY29udHJhc3RzLmFncmVlJENobC5Db2xGPC1pZmVsc2UoVG9sX2NvbnRyYXN0cy5hZ3JlZSRwX0NobG9yb3BoeWxsPT0xICYgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVG9sX2NvbnRyYXN0cy5hZ3JlZSRwX0NobG9yb3BoeWxsPT1Ub2xfY29udHJhc3RzLmFncmVlJHBfQ29sb3JfRnVsbFNldCAmDQpUb2xfY29udHJhc3RzLmFncmVlJEVzdGltYXRlX0NobG9yb3BoeWxsPT1Ub2xfY29udHJhc3RzLmFncmVlJEVzdGltYXRlX0NvbG9yX0Z1bGxTZXQsIDEsIA0KaWZlbHNlKFRvbF9jb250cmFzdHMuYWdyZWUkcF9DaGxvcm9waHlsbD09MCAmDQogICAgICAgICBUb2xfY29udHJhc3RzLmFncmVlJHBfQ2hsb3JvcGh5bGw9PVRvbF9jb250cmFzdHMuYWdyZWUkcF9Db2xvcl9GdWxsU2V0LCAxLCAwKSkNCg0KVG9sX2NvbnRyYXN0cy5hZ3JlZSRDaGwuQ29sVFA8LWlmZWxzZShUb2xfY29udHJhc3RzLmFncmVlJHBfQ2hsb3JvcGh5bGw9PTEgJiANClRvbF9jb250cmFzdHMuYWdyZWUkcF9DaGxvcm9waHlsbD09VG9sX2NvbnRyYXN0cy5hZ3JlZSRwX0NvbG9yX1RQICYgICAgICAgICAgICAgICAgICAgICAgICAgIFRvbF9jb250cmFzdHMuYWdyZWUkRXN0aW1hdGVfQ2hsb3JvcGh5bGw9PVRvbF9jb250cmFzdHMuYWdyZWUkRXN0aW1hdGVfQ29sb3JfVFAsIDEsIA0KaWZlbHNlKFRvbF9jb250cmFzdHMuYWdyZWUkcF9DaGxvcm9waHlsbD09MCAmDQogICAgICAgICBUb2xfY29udHJhc3RzLmFncmVlJHBfQ2hsb3JvcGh5bGw9PVRvbF9jb250cmFzdHMuYWdyZWUkcF9Db2xvcl9UUCwgMSwgMCkpDQoNClRvbF9jb250cmFzdHMuYWdyZWUkU3ltLkNvbEY8LWlmZWxzZShUb2xfY29udHJhc3RzLmFncmVlJHBfU3ltYmlvbnRzPT0xICYNClRvbF9jb250cmFzdHMuYWdyZWUkcF9TeW1iaW9udHM9PVRvbF9jb250cmFzdHMuYWdyZWUkcF9Db2xvcl9GdWxsU2V0ICYgVG9sX2NvbnRyYXN0cy5hZ3JlZSRFc3RpbWF0ZV9TeW1iaW9udHM9PVRvbF9jb250cmFzdHMuYWdyZWUkRXN0aW1hdGVfQ29sb3JfRnVsbFNldCwgMSwNCmlmZWxzZShUb2xfY29udHJhc3RzLmFncmVlJHBfU3ltYmlvbnRzPT0wICYNCiAgICAgICAgIFRvbF9jb250cmFzdHMuYWdyZWUkcF9TeW1iaW9udHM9PVRvbF9jb250cmFzdHMuYWdyZWUkcF9Db2xvcl9GdWxsU2V0LCAxLCAwKSkNCg0KVG9sX2NvbnRyYXN0cy5hZ3JlZSRTeW0uQ29sVFA8LWlmZWxzZShUb2xfY29udHJhc3RzLmFncmVlJHBfU3ltYmlvbnRzPT0xICYNClRvbF9jb250cmFzdHMuYWdyZWUkcF9TeW1iaW9udHM9PVRvbF9jb250cmFzdHMuYWdyZWUkcF9Db2xvcl9UUCAmIFRvbF9jb250cmFzdHMuYWdyZWUkRXN0aW1hdGVfU3ltYmlvbnRzPT1Ub2xfY29udHJhc3RzLmFncmVlJEVzdGltYXRlX0NvbG9yX1RQLCAxLA0KaWZlbHNlKFRvbF9jb250cmFzdHMuYWdyZWUkcF9TeW1iaW9udHM9PTAgJg0KICAgICAgICAgVG9sX2NvbnRyYXN0cy5hZ3JlZSRwX1N5bWJpb250cz09VG9sX2NvbnRyYXN0cy5hZ3JlZSRwX0NvbG9yX1RQLCAxLCAwKSkNCg0KVG9sX2NvbnRyYXN0cy5hZ3JlZSRDb2xGLkNvbFRQPC1pZmVsc2UoVG9sX2NvbnRyYXN0cy5hZ3JlZSRwX0NvbG9yX0Z1bGxTZXQ9PTEgJg0KVG9sX2NvbnRyYXN0cy5hZ3JlZSRwX0NvbG9yX0Z1bGxTZXQ9PVRvbF9jb250cmFzdHMuYWdyZWUkcF9Db2xvcl9UUCAmIFRvbF9jb250cmFzdHMuYWdyZWUkRXN0aW1hdGVfQ29sb3JfRnVsbFNldD09VG9sX2NvbnRyYXN0cy5hZ3JlZSRFc3RpbWF0ZV9Db2xvcl9UUCwgMSwgDQppZmVsc2UoVG9sX2NvbnRyYXN0cy5hZ3JlZSRwX0NvbG9yX0Z1bGxTZXQ9PTAgJg0KICAgICAgICAgVG9sX2NvbnRyYXN0cy5hZ3JlZSRwX0NvbG9yX0Z1bGxTZXQ9PVRvbF9jb250cmFzdHMuYWdyZWUkcF9Db2xvcl9UUCwgMSwgMCkpDQoNCiMjQ29udmVydCB0byBsb25nIHRvIGNhbGN1bGF0ZSBpbnN0YW5jZXMgb2YgYWdyZWVtZW50DQpUb2xfY29udHJhc3RzLmFncmVlLmxvbmc8LVRvbF9jb250cmFzdHMuYWdyZWUgJT4lIHBpdm90X2xvbmdlcihjb2xzPWMoIkNobC5TeW0iLCAiQ2hsLkNvbEYiLCAiQ2hsLkNvbFRQIiwgIlN5bS5Db2xGIiwgIlN5bS5Db2xUUCIsICJDb2xGLkNvbFRQIiksIG5hbWVzX3RvPSJDb21wYXJlIiwgdmFsdWVzX3RvPSJBZ3JlZSIpDQoNCiMjU3VtIENhc2VzIG9mIEFncmVlbWVudA0KVG9sX2NvbnRyYXN0cy5hZ3JlZS5zdW08LWFnZ3JlZ2F0ZShUb2xfY29udHJhc3RzLmFncmVlLmxvbmckQWdyZWUsIGxpc3QoVG9sX2NvbnRyYXN0cy5hZ3JlZS5sb25nJENvbXBhcmUpLCBzdW0pDQpuYW1lcyhUb2xfY29udHJhc3RzLmFncmVlLnN1bSk8LWMoIkNvbXBhcmUiLCAiQWdyZWUiKQ0KDQojI1RvdGFsIFBhaXJ3aXNlIENvbXBhcmlzb25zDQpUb2xfY29udHJhc3RzLmFncmVlLnN1bSRUb3RhbDwtYWdncmVnYXRlKFRvbF9jb250cmFzdHMuYWdyZWUubG9uZyRBZ3JlZSwgbGlzdChUb2xfY29udHJhc3RzLmFncmVlLmxvbmckQ29tcGFyZSksIGZ1bmN0aW9uKHgpIGxlbmd0aCh4KSlbLDJdDQpgYGANCg0KDQojIyMjIENvbXBhcmUgUHJvcG9ydGlvbiBBZ3JlZW1lbnQNCmBgYHtyfQ0KcHJvcC50ZXN0KFRvbF9jb250cmFzdHMuYWdyZWUuc3VtJEFncmVlLCBUb2xfY29udHJhc3RzLmFncmVlLnN1bSRUb3RhbCkNCg0KYGBgDQoNCk5vIHNpZ25pZmljYW50IGRpZmZlcmVuY2UgaW4gdGhlIHByb3BvcnRpb24gb2YgYWdyZWVtZW50IGluIGRldGVjdGluZyBwYWlyd2lzZSBkaWZmZXJlbmNlcyBpbiB0aGVybWFsIHRvbGVyYW5jZSBhY3Jvc3MgY29tcGFyaXNvbnMgb2YgdHJhZGl0aW9uYWwgYmxlYWNoaW5nIG9yIGNvbG9yIHNjb3JlIG1ldGhvZHMgKFBlYXJzb24ncyBjaGktc3F1YXJlZCB0ZXN0IHAtdmFsdWUgPSAwLjMwMTMpDQoNCg0KIyMjIENvbXBhcmUgQWdyZWVtZW50IGFjcm9zcyBTZWFzb25zDQoNCmBgYHtyfQ0KIyNTdW0gQ2FzZXMgb2YgQWdyZWVtZW50IGJ5IENvbXBhcmlzb24gYW5kIFRpbWVwb2ludA0KVG9sX2NvbnRyYXN0cy5hZ3JlZS5zdW0udHA8LWFnZ3JlZ2F0ZShUb2xfY29udHJhc3RzLmFncmVlLmxvbmckQWdyZWUsIGxpc3QoVG9sX2NvbnRyYXN0cy5hZ3JlZS5sb25nJFRpbWVQLCBUb2xfY29udHJhc3RzLmFncmVlLmxvbmckQ29tcGFyZSksIHN1bSkNCm5hbWVzKFRvbF9jb250cmFzdHMuYWdyZWUuc3VtLnRwKTwtYygiVGltZVAiLCAiQ29tcGFyZSIsICJBZ3JlZSIpDQoNCiMjVG90YWwgUGFpcndpc2UgQ29tcGFyaXNvbnMNClRvbF9jb250cmFzdHMuYWdyZWUuc3VtLnRwJFRvdGFsPC1hZ2dyZWdhdGUoVG9sX2NvbnRyYXN0cy5hZ3JlZS5sb25nJEFncmVlLCBsaXN0KFRvbF9jb250cmFzdHMuYWdyZWUubG9uZyRUaW1lUCwgVG9sX2NvbnRyYXN0cy5hZ3JlZS5sb25nJENvbXBhcmUpLCBmdW5jdGlvbih4KSBsZW5ndGgoeCkpWywzXQ0KDQoNCmBgYA0KDQoNCiMjIyMgQ2hsIHZzIFN5bQ0KYGBge3J9DQojI1N1YnNldCBieSBDb21wYXJpc29uDQpUb2xfY29udHJhc3RzLmFncmVlLkNobC5TeW08LXN1YnNldChUb2xfY29udHJhc3RzLmFncmVlLnN1bS50cCwgQ29tcGFyZT09IkNobC5TeW0iKQ0KDQojI0NvbXBhcmUgUHJvcG9ydGlvbnMgYmV0d2VlbiBUaW1lcG9pbnRzDQpwcm9wLnRlc3QoVG9sX2NvbnRyYXN0cy5hZ3JlZS5DaGwuU3ltJEFncmVlLCBUb2xfY29udHJhc3RzLmFncmVlLkNobC5TeW0kVG90YWwpDQoNCmBgYA0KDQoNCiMjIyMgQ2hsIHZzIENvbG9yIEZ1bGwNCmBgYHtyfQ0KIyNTdWJzZXQgYnkgQ29tcGFyaXNvbg0KVG9sX2NvbnRyYXN0cy5hZ3JlZS5DaGwuQ29sRjwtc3Vic2V0KFRvbF9jb250cmFzdHMuYWdyZWUuc3VtLnRwLCBDb21wYXJlPT0iQ2hsLkNvbEYiKQ0KDQojI0NvbXBhcmUgUHJvcG9ydGlvbnMgYmV0d2VlbiBUaW1lcG9pbnRzDQpwcm9wLnRlc3QoVG9sX2NvbnRyYXN0cy5hZ3JlZS5DaGwuQ29sRiRBZ3JlZSwgVG9sX2NvbnRyYXN0cy5hZ3JlZS5DaGwuQ29sRiRUb3RhbCkNCg0KYGBgDQoNCiMjIyMgQ2hsIHZzIENvbG9yIFRpbWVwb2ludA0KYGBge3J9DQojI1N1YnNldCBieSBDb21wYXJpc29uDQpUb2xfY29udHJhc3RzLmFncmVlLkNobC5Db2xUUDwtc3Vic2V0KFRvbF9jb250cmFzdHMuYWdyZWUuc3VtLnRwLCBDb21wYXJlPT0iQ2hsLkNvbFRQIikNCg0KIyNDb21wYXJlIFByb3BvcnRpb25zIGJldHdlZW4gVGltZXBvaW50cw0KcHJvcC50ZXN0KFRvbF9jb250cmFzdHMuYWdyZWUuQ2hsLkNvbFRQJEFncmVlLCBUb2xfY29udHJhc3RzLmFncmVlLkNobC5Db2xUUCRUb3RhbCkNCg0KYGBgDQoNCg0KIyMjIyBTeW0gdnMgQ29sb3IgRnVsbA0KYGBge3J9DQojI1N1YnNldCBieSBDb21wYXJpc29uDQpUb2xfY29udHJhc3RzLmFncmVlLlN5bS5Db2xGPC1zdWJzZXQoVG9sX2NvbnRyYXN0cy5hZ3JlZS5zdW0udHAsIENvbXBhcmU9PSJTeW0uQ29sRiIpDQoNCiMjQ29tcGFyZSBQcm9wb3J0aW9ucyBiZXR3ZWVuIFRpbWVwb2ludHMNCnByb3AudGVzdChUb2xfY29udHJhc3RzLmFncmVlLlN5bS5Db2xGJEFncmVlLCBUb2xfY29udHJhc3RzLmFncmVlLlN5bS5Db2xGJFRvdGFsKQ0KDQpgYGANCg0KDQojIyMjIFN5bSB2cyBDb2xvciBUaW1lcG9pbnQNCmBgYHtyfQ0KIyNTdWJzZXQgYnkgQ29tcGFyaXNvbg0KVG9sX2NvbnRyYXN0cy5hZ3JlZS5TeW0uQ29sVFA8LXN1YnNldChUb2xfY29udHJhc3RzLmFncmVlLnN1bS50cCwgQ29tcGFyZT09IlN5bS5Db2xUUCIpDQoNCiMjQ29tcGFyZSBQcm9wb3J0aW9ucyBiZXR3ZWVuIFRpbWVwb2ludHMNCnByb3AudGVzdChUb2xfY29udHJhc3RzLmFncmVlLlN5bS5Db2xUUCRBZ3JlZSwgVG9sX2NvbnRyYXN0cy5hZ3JlZS5TeW0uQ29sVFAkVG90YWwpDQoNCmBgYA0KDQoNCiMjIyMgQ29sb3IgRnVsbCB2cyBDb2xvciBUaW1lcG9pbnQNCmBgYHtyfQ0KIyNTdWJzZXQgYnkgQ29tcGFyaXNvbg0KVG9sX2NvbnRyYXN0cy5hZ3JlZS5Db2xGLkNvbFRQPC1zdWJzZXQoVG9sX2NvbnRyYXN0cy5hZ3JlZS5zdW0udHAsIENvbXBhcmU9PSJDb2xGLkNvbFRQIikNCg0KIyNDb21wYXJlIFByb3BvcnRpb25zIGJldHdlZW4gVGltZXBvaW50cw0KcHJvcC50ZXN0KFRvbF9jb250cmFzdHMuYWdyZWUuQ29sRi5Db2xUUCRBZ3JlZSwgVG9sX2NvbnRyYXN0cy5hZ3JlZS5Db2xGLkNvbFRQJFRvdGFsKQ0KDQpgYGANCg0KDQojIEZpZ3VyZXMNCg0KIyMjIEZpZ3VyZSBTMiBUb2xlcmFuY2UgQWNyb3NzIE1ldHJpY3MNCg0KIyMjIyBVcGRhdGUgZm9yIFBhbmVsDQpgYGB7cn0NClRvbF9DaGxfVzJfU0cucGxvdC5maWc8LWdncGxvdChUb2xfQ2hsX1cyX1NHLCBhZXMoeD1TaXRlLkdlbm8sIHk9Q2hsLnByb3AsIGNvbG91cj1HZW5vdHlwZSkpICsgDQogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49Q2hsLnByb3Atc2UsIHltYXg9Q2hsLnByb3Arc2UpLCB3aWR0aD1jYXAuc3osIGxpbmV3aWR0aD1iYXIuc3opKw0KICBnZW9tX3BvaW50KHNpemU9cG9pbnQuc3opKyANCiAgZ2d0aXRsZSgiU3VtbWVyIDEiKSsNCiAgdGhlbWVfY2xhc3NpYygpKw0KICB0aGVtZSggYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSBheGlzLnRpdGxlLnN6KSwgDQogICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IGF4aXMudGl0bGUuc3opLCANCiAgICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksDQogICAgICAgICBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLCANCiAgICAgICAgIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPWxlZy50eHQuc3opLA0KICAgICAgICAgbGVnZW5kLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPWxlZy50aXRsZS5zeiksIA0KICAgICAgICAgbGVnZW5kLmJveC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGNvbG9yID0gImJsYWNrIiksDQogICAgICAgICBsZWdlbmQucG9zaXRpb249InRvcCIsIA0KICAgICAgICAgbGVnZW5kLmRpcmVjdGlvbj0iaG9yaXpvbnRhbCIsDQogICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSBwbG90LnRpdGxlLnN6LCBjb2xvdXI9ImJsYWNrIiwgaGp1c3QgPSAwLjUpKSsNCiAgbGFicyh4PSIiLCB5PSJQcm9wb3J0aW9uIENobG9yb3BoeWxsIFJldGFpbmVkIikrDQogIHlsaW0oMCwgMSkrIA0KICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscz1jKCIiLCJLbGVpbiIsIiIsIiIsIlNvbWV0aGluZyBTcGVjaWFsIiwiIikpKw0KICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gR2Vuby5jb2xvcnMubykrIA0KICBzdGF0X3B2YWx1ZV9tYW51YWwoZGF0YT1Ub2xfQ2hsX1cyX2xtLnAsICB5LnBvc2l0aW9uPTAuNCwgc3RlcC5pbmNyZWFzZT0wLjI1LCBsYWJlbD0iU2lnIiwgaGlkZS5ucz1UUlVFKQ0KDQoNClRvbF9DaGxfTTFfU0cucGxvdC5maWc8LWdncGxvdChUb2xfQ2hsX00xX1NHLCBhZXMoeD1TaXRlLkdlbm8sIHk9Q2hsLnByb3AsIGNvbG91cj1HZW5vdHlwZSkpICsgDQogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49Q2hsLnByb3Atc2UsIHltYXg9Q2hsLnByb3Arc2UpLCB3aWR0aD1jYXAuc3osIGxpbmV3aWR0aD1iYXIuc3opKw0KICBnZW9tX3BvaW50KHNpemU9cG9pbnQuc3opKyANCiAgZ2d0aXRsZSgiU3VtbWVyIDIiKSsNCiAgdGhlbWVfY2xhc3NpYygpKw0KICB0aGVtZSggYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSBheGlzLnRpdGxlLnN6KSwgDQogICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IGF4aXMudGl0bGUuc3opLCANCiAgICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksDQogICAgICAgICBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLCANCiAgICAgICAgIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPWxlZy50eHQuc3opLA0KICAgICAgICAgbGVnZW5kLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPWxlZy50aXRsZS5zeiksIA0KICAgICAgICAgbGVnZW5kLmJveC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGNvbG9yID0gImJsYWNrIiksDQogICAgICAgICBsZWdlbmQucG9zaXRpb249InRvcCIsIA0KICAgICAgICAgbGVnZW5kLmRpcmVjdGlvbj0iaG9yaXpvbnRhbCIsDQogICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSBwbG90LnRpdGxlLnN6LCBjb2xvdXI9ImJsYWNrIiwgaGp1c3QgPSAwLjUpKSsNCiAgbGFicyh4PSIiLCB5PSIiKSsNCiAgeWxpbSgwLCAxKSsgDQogIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzPWMoIiIsIktsZWluIiwiIiwiIiwiU29tZXRoaW5nIFNwZWNpYWwiLCIiKSkrDQogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBHZW5vLmNvbG9ycy5vKSsgDQogIHN0YXRfcHZhbHVlX21hbnVhbChkYXRhPVRvbF9DaGxfTTFfbG0ucCwgIHkucG9zaXRpb249MC40LCBzdGVwLmluY3JlYXNlPTAuMjUsIGxhYmVsPSJTaWciLCBoaWRlLm5zPVRSVUUpDQoNCg0KVG9sX0NobF9NNF9TRy5wbG90LmZpZzwtZ2dwbG90KFRvbF9DaGxfTTRfU0csIGFlcyh4PVNpdGUuR2VubywgeT1DaGwucHJvcCwgY29sb3VyPUdlbm90eXBlKSkgKyANCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1DaGwucHJvcC1zZSwgeW1heD1DaGwucHJvcCtzZSksIHdpZHRoPWNhcC5zeiwgbGluZXdpZHRoPWJhci5zeikrDQogIGdlb21fcG9pbnQoc2l6ZT1wb2ludC5zeikrIA0KICBnZ3RpdGxlKCJXaW50ZXIiKSsNCiAgdGhlbWVfY2xhc3NpYygpKw0KICB0aGVtZSggYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSBheGlzLnRpdGxlLnN6KSwgDQogICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IGF4aXMudGl0bGUuc3opLCANCiAgICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksDQogICAgICAgICBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLCANCiAgICAgICAgIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPWxlZy50eHQuc3opLA0KICAgICAgICAgbGVnZW5kLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPWxlZy50aXRsZS5zeiksIA0KICAgICAgICAgbGVnZW5kLmJveC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGNvbG9yID0gImJsYWNrIiksDQogICAgICAgICBsZWdlbmQucG9zaXRpb249InRvcCIsIA0KICAgICAgICAgbGVnZW5kLmRpcmVjdGlvbj0iaG9yaXpvbnRhbCIsDQogICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSBwbG90LnRpdGxlLnN6LCBjb2xvdXI9ImJsYWNrIiwgaGp1c3QgPSAwLjUpKSsNCiAgbGFicyh4PSIiLCB5PSIiKSsNCiAgeWxpbSgwLCAxKSsgDQogIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzPWMoIiIsIktsZWluIiwiIiwiIiwiU29tZXRoaW5nIFNwZWNpYWwiLCIiKSkrDQogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBHZW5vLmNvbG9ycy5vKSsgDQogIHN0YXRfcHZhbHVlX21hbnVhbChkYXRhPVRvbF9DaGxfTTRfbG0ucCwgIHkucG9zaXRpb249MC41NSwgc3RlcC5pbmNyZWFzZT0wLjIwLCBsYWJlbD0iU2lnIiwgaGlkZS5ucz1UUlVFKQ0KDQoNClRvbF9TeW1fVzJfU0cucGxvdC5maWc8LWdncGxvdChUb2xfU3ltX1cyX1NHLCBhZXMoeD1TaXRlLkdlbm8sIHk9U3ltLnByb3AsIGNvbG91cj1HZW5vdHlwZSkpICsgDQogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49U3ltLnByb3Atc2UsIHltYXg9U3ltLnByb3Arc2UpLCB3aWR0aD1jYXAuc3osIGxpbmV3aWR0aD1iYXIuc3opKw0KICBnZW9tX3BvaW50KHNpemU9cG9pbnQuc3opKyANCiAgdGhlbWVfY2xhc3NpYygpKw0KICB0aGVtZSggYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSBheGlzLnRpdGxlLnN6KSwgDQogICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IGF4aXMudGl0bGUuc3opLCANCiAgICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksDQogICAgICAgICBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLCANCiAgICAgICAgIGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpKw0KICBsYWJzKHg9IlNpdGUgYW5kIEdlbm90eXBlIiwgeT0iUHJvcG9ydGlvbiBTeW1iaW9udHMgUmV0YWluZWQiKSsNCiAgeWxpbSgwLCAxLjUpKyANCiAgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHM9YygiIiwiS2xlaW4iLCIiLCIiLCJTb21ldGhpbmcgU3BlY2lhbCIsIiIpKSsNCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IEdlbm8uY29sb3JzLm8pKyANCiAgc3RhdF9wdmFsdWVfbWFudWFsKGRhdGE9VG9sX1N5bV9XMl9sbS5wLCAgeS5wb3NpdGlvbj0wLjk1LCBzdGVwLmluY3JlYXNlPTAuMTUsIGxhYmVsPSJTaWciLCBoaWRlLm5zPVRSVUUpDQoNCg0KVG9sX1N5bV9NMV9TRy5wbG90LmZpZzwtZ2dwbG90KFRvbF9TeW1fTTFfU0csIGFlcyh4PVNpdGUuR2VubywgeT1TeW0ucHJvcCwgY29sb3VyPUdlbm90eXBlKSkgKyANCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1TeW0ucHJvcC1zZSwgeW1heD1TeW0ucHJvcCtzZSksIHdpZHRoPWNhcC5zeiwgbGluZXdpZHRoPWJhci5zeikrDQogIGdlb21fcG9pbnQoc2l6ZT1wb2ludC5zeikrIA0KICB0aGVtZV9jbGFzc2ljKCkrDQogIHRoZW1lKCBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IGF4aXMudGl0bGUuc3opLCANCiAgICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIA0KICAgICAgICAgYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50eHQuc3osIGNvbG91cj0iYmxhY2siKSwNCiAgICAgICAgIGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksIA0KICAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJub25lIikrDQogIGxhYnMoeD0iU2l0ZSBhbmQgR2Vub3R5cGUiLCB5PSIiKSsNCiAgeWxpbSgwLCAxLjUpKyANCiAgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHM9YygiIiwiS2xlaW4iLCIiLCIiLCJTb21ldGhpbmcgU3BlY2lhbCIsIiIpKSsNCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IEdlbm8uY29sb3JzLm8pKyANCiAgc3RhdF9wdmFsdWVfbWFudWFsKGRhdGE9VG9sX1N5bV9NMV9sbS5wLCAgeS5wb3NpdGlvbj0wLjk1LCBzdGVwLmluY3JlYXNlPTAuMTUsIGxhYmVsPSJTaWciLCBoaWRlLm5zPVRSVUUpDQoNCg0KVG9sX1N5bV9NNF9TRy5wbG90LmZpZzwtZ2dwbG90KFRvbF9TeW1fTTRfU0csIGFlcyh4PVNpdGUuR2VubywgeT1TeW0ucHJvcCwgY29sb3VyPUdlbm90eXBlKSkgKyANCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1TeW0ucHJvcC1zZSwgeW1heD1TeW0ucHJvcCtzZSksIHdpZHRoPWNhcC5zeiwgbGluZXdpZHRoPWJhci5zeikrDQogIGdlb21fcG9pbnQoc2l6ZT1wb2ludC5zeikrIA0KICB0aGVtZV9jbGFzc2ljKCkrDQogIHRoZW1lKCBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IGF4aXMudGl0bGUuc3opLCANCiAgICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIA0KICAgICAgICAgYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50eHQuc3osIGNvbG91cj0iYmxhY2siKSwNCiAgICAgICAgIGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksIA0KICAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJub25lIikrDQogIGxhYnMoeD0iU2l0ZSBhbmQgR2Vub3R5cGUiLCB5PSIiKSsNCiAgeWxpbSgwLCAxLjUpKyANCiAgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHM9YygiIiwiS2xlaW4iLCIiLCIiLCJTb21ldGhpbmcgU3BlY2lhbCIsIiIpKSsNCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IEdlbm8uY29sb3JzLm8pKyANCiAgc3RhdF9wdmFsdWVfbWFudWFsKGRhdGE9VG9sX1N5bV9NNF9sbS5wLCAgeS5wb3NpdGlvbj0xLjEsIHN0ZXAuaW5jcmVhc2U9MC4xNSwgbGFiZWw9IlNpZyIsIGhpZGUubnM9VFJVRSkNCg0KDQpUb2xfU2NvcmVGX1cyX1NHLnBsb3QuZmlnPC1nZ3Bsb3QoVG9sX1Njb3JlRl9XMl9TRywgYWVzKHg9U2l0ZS5HZW5vLCB5PVNjb3JlX0Z1bGwucHJvcCwgY29sb3VyPUdlbm90eXBlKSkgKyANCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1TY29yZV9GdWxsLnByb3Atc2UsIHltYXg9U2NvcmVfRnVsbC5wcm9wK3NlKSwgd2lkdGg9Y2FwLnN6LCBsaW5ld2lkdGg9YmFyLnN6KSsNCiAgZ2VvbV9wb2ludChzaXplPXBvaW50LnN6KSsgDQogIHRoZW1lX2NsYXNzaWMoKSsNCiAgdGhlbWUoIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIA0KICAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSBheGlzLnRpdGxlLnN6KSwgDQogICAgICAgICBheGlzLnRleHQueD1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLA0KICAgICAgICAgYXhpcy50ZXh0Lnk9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50eHQuc3osIGNvbG91cj0iYmxhY2siKSwgDQogICAgICAgICBsZWdlbmQucG9zaXRpb249Im5vbmUiKSsNCiAgbGFicyh4PSIiLCB5PSJQcm9wb3J0aW9uIENvbG9yIFJldGFpbmVkIChGdWxsKSIpKw0KICB5bGltKDAuMjUsIDEuNSkrIA0KICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscz1jKCIiLCJLbGVpbiIsIiIsIiIsIlNvbWV0aGluZyBTcGVjaWFsIiwiIikpKw0KICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gR2Vuby5jb2xvcnMubykrIA0KICBzdGF0X3B2YWx1ZV9tYW51YWwoZGF0YT1Ub2xfU2NvcmVGX1cyX2xtLnAsICB5LnBvc2l0aW9uPTAuOSwgc3RlcC5pbmNyZWFzZT0wLjM1LCBsYWJlbD0iU2lnIiwgaGlkZS5ucz1UUlVFKQ0KDQoNClRvbF9TY29yZUZfTTFfU0cucGxvdC5maWc8LWdncGxvdChUb2xfU2NvcmVGX00xX1NHLCBhZXMoeD1TaXRlLkdlbm8sIHk9U2NvcmVfRnVsbC5wcm9wLCBjb2xvdXI9R2Vub3R5cGUpKSArIA0KICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluPVNjb3JlX0Z1bGwucHJvcC1zZSwgeW1heD1TY29yZV9GdWxsLnByb3Arc2UpLCB3aWR0aD1jYXAuc3osIGxpbmV3aWR0aD1iYXIuc3opKw0KICBnZW9tX3BvaW50KHNpemU9cG9pbnQuc3opKyANCiAgdGhlbWVfY2xhc3NpYygpKw0KICB0aGVtZSggYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSBheGlzLnRpdGxlLnN6KSwgDQogICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IGF4aXMudGl0bGUuc3opLCANCiAgICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksDQogICAgICAgICBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLCANCiAgICAgICAgIGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpKw0KICBsYWJzKHg9IiIsIHk9IiIpKw0KICB5bGltKDAuMjUsIDEuNSkrIA0KICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscz1jKCIiLCJLbGVpbiIsIiIsIiIsIlNvbWV0aGluZyBTcGVjaWFsIiwiIikpKw0KICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gR2Vuby5jb2xvcnMubykrIA0KICBzdGF0X3B2YWx1ZV9tYW51YWwoZGF0YT1Ub2xfU2NvcmVGX00xX2xtLnAsICB5LnBvc2l0aW9uPTEuMSwgc3RlcC5pbmNyZWFzZT0wLjIsIGxhYmVsPSJTaWciLCBoaWRlLm5zPVRSVUUpDQoNCg0KVG9sX1Njb3JlRl9NNF9TRy5wbG90LmZpZzwtZ2dwbG90KFRvbF9TY29yZUZfTTRfU0csIGFlcyh4PVNpdGUuR2VubywgeT1TY29yZV9GdWxsLnByb3AsIGNvbG91cj1HZW5vdHlwZSkpICsgDQogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49U2NvcmVfRnVsbC5wcm9wLXNlLCB5bWF4PVNjb3JlX0Z1bGwucHJvcCtzZSksIHdpZHRoPWNhcC5zeiwgbGluZXdpZHRoPWJhci5zeikrDQogIGdlb21fcG9pbnQoc2l6ZT1wb2ludC5zeikrIA0KICB0aGVtZV9jbGFzc2ljKCkrDQogIHRoZW1lKCBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IGF4aXMudGl0bGUuc3opLCANCiAgICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIA0KICAgICAgICAgYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50eHQuc3osIGNvbG91cj0iYmxhY2siKSwNCiAgICAgICAgIGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksIA0KICAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJub25lIikrDQogIGxhYnMoeD0iIiwgeT0iIikrDQogIHlsaW0oMC4yNSwgMS41KSsgDQogIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzPWMoIiIsIktsZWluIiwiIiwiIiwiU29tZXRoaW5nIFNwZWNpYWwiLCIiKSkrDQogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBHZW5vLmNvbG9ycy5vKSsgDQogIHN0YXRfcHZhbHVlX21hbnVhbChkYXRhPVRvbF9TY29yZUZfTTRfbG0ucCwgIHkucG9zaXRpb249MS4xLCBzdGVwLmluY3JlYXNlPTAuMjIsIGxhYmVsPSJTaWciLCBoaWRlLm5zPVRSVUUpDQoNCg0KVG9sX1Njb3JlVFBfVzJfU0cucGxvdC5maWc8LWdncGxvdChUb2xfU2NvcmVUUF9XMl9TRywgYWVzKHg9U2l0ZS5HZW5vLCB5PVNjb3JlX1RQLnByb3AsIGNvbG91cj1HZW5vdHlwZSkpICsgDQogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49U2NvcmVfVFAucHJvcC1zZSwgeW1heD1TY29yZV9UUC5wcm9wK3NlKSwgd2lkdGg9Y2FwLnN6LCBsaW5ld2lkdGg9YmFyLnN6KSsNCiAgZ2VvbV9wb2ludChzaXplPXBvaW50LnN6KSsgDQogIHRoZW1lX2NsYXNzaWMoKSsNCiAgdGhlbWUoIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIA0KICAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSBheGlzLnRpdGxlLnN6KSwgDQogICAgICAgICBheGlzLnRleHQueD1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLA0KICAgICAgICAgYXhpcy50ZXh0Lnk9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50eHQuc3osIGNvbG91cj0iYmxhY2siKSwgDQogICAgICAgICBsZWdlbmQucG9zaXRpb249Im5vbmUiKSsNCiAgbGFicyh4PSIiLCB5PSJQcm9wb3J0aW9uIENvbG9yIFJldGFpbmVkIChTcGxpdCkiKSsNCiAgeWxpbSgwLjI1LCAxLjUpKyANCiAgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHM9YygiIiwiS2xlaW4iLCIiLCIiLCJTb21ldGhpbmcgU3BlY2lhbCIsIiIpKSsNCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IEdlbm8uY29sb3JzLm8pKyANCiAgc3RhdF9wdmFsdWVfbWFudWFsKGRhdGE9VG9sX1Njb3JlVFBfVzJfbG0ucCwgIHkucG9zaXRpb249MSwgc3RlcC5pbmNyZWFzZT0wLjQ1LCBsYWJlbD0iU2lnIiwgaGlkZS5ucz1UUlVFKQ0KDQoNClRvbF9TY29yZVRQX00xX1NHLnBsb3QuZmlnPC1nZ3Bsb3QoVG9sX1Njb3JlVFBfTTFfU0csIGFlcyh4PVNpdGUuR2VubywgeT1TY29yZV9UUC5wcm9wLCBjb2xvdXI9R2Vub3R5cGUpKSArIA0KICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluPVNjb3JlX1RQLnByb3Atc2UsIHltYXg9U2NvcmVfVFAucHJvcCtzZSksIHdpZHRoPWNhcC5zeiwgbGluZXdpZHRoPWJhci5zeikrDQogIGdlb21fcG9pbnQoc2l6ZT1wb2ludC5zeikrIA0KICB0aGVtZV9jbGFzc2ljKCkrDQogIHRoZW1lKCBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IGF4aXMudGl0bGUuc3opLCANCiAgICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIA0KICAgICAgICAgYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50eHQuc3osIGNvbG91cj0iYmxhY2siKSwNCiAgICAgICAgIGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksIA0KICAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJub25lIikrDQogIGxhYnMoeD0iIiwgeT0iIikrDQogIHlsaW0oMC4yNSwgMS41KSsgDQogIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzPWMoIiIsIktsZWluIiwiIiwiIiwiU29tZXRoaW5nIFNwZWNpYWwiLCIiKSkrDQogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBHZW5vLmNvbG9ycy5vKSsgDQogIHN0YXRfcHZhbHVlX21hbnVhbChkYXRhPVRvbF9TY29yZVRQX00xX2xtLnAsICB5LnBvc2l0aW9uPTEuMDUsIHN0ZXAuaW5jcmVhc2U9MC4zLCBsYWJlbD0iU2lnIiwgaGlkZS5ucz1UUlVFKQ0KDQoNClRvbF9TY29yZVRQX000X1NHLnBsb3QuZmlnPC1nZ3Bsb3QoVG9sX1Njb3JlVFBfTTRfU0csIGFlcyh4PVNpdGUuR2VubywgeT1TY29yZV9UUC5wcm9wLCBjb2xvdXI9R2Vub3R5cGUpKSArIA0KICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluPVNjb3JlX1RQLnByb3Atc2UsIHltYXg9U2NvcmVfVFAucHJvcCtzZSksIHdpZHRoPWNhcC5zeiwgbGluZXdpZHRoPWJhci5zeikrDQogIGdlb21fcG9pbnQoc2l6ZT1wb2ludC5zeikrIA0KICB0aGVtZV9jbGFzc2ljKCkrDQogIHRoZW1lKCBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IGF4aXMudGl0bGUuc3opLCANCiAgICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIA0KICAgICAgICAgYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50eHQuc3osIGNvbG91cj0iYmxhY2siKSwNCiAgICAgICAgIGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksIA0KICAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJub25lIikrDQogIGxhYnMoeD0iIiwgeT0iIikrDQogIHlsaW0oMC4yNSwgMS41KSsgDQogIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzPWMoIiIsIktsZWluIiwiIiwiIiwiU29tZXRoaW5nIFNwZWNpYWwiLCIiKSkrDQogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBHZW5vLmNvbG9ycy5vKSsgDQogIHN0YXRfcHZhbHVlX21hbnVhbChkYXRhPVRvbF9TY29yZVRQX000X2xtLnAsICB5LnBvc2l0aW9uPTEuMSwgc3RlcC5pbmNyZWFzZT0wLjQsIGxhYmVsPSJTaWciLCBoaWRlLm5zPVRSVUUpDQoNCg0KYGBgDQoNCg0KDQojIyMjIEZpZ3VyZSBTMg0KYGBge3J9DQojI0NyZWF0ZSBQYW5lbA0KVG9sZXJhbmNlX2ZpZzwtcGxvdF9ncmlkKFRvbF9DaGxfVzJfU0cucGxvdC5maWcsIFRvbF9DaGxfTTFfU0cucGxvdC5maWcsIFRvbF9DaGxfTTRfU0cucGxvdC5maWcsDQogICAgICAgICAgICAgICAgICBUb2xfU2NvcmVGX1cyX1NHLnBsb3QuZmlnLCBUb2xfU2NvcmVGX00xX1NHLnBsb3QuZmlnLCBUb2xfU2NvcmVGX000X1NHLnBsb3QuZmlnLA0KICAgICAgICAgICAgICAgICAgVG9sX1Njb3JlVFBfVzJfU0cucGxvdC5maWcsIFRvbF9TY29yZVRQX00xX1NHLnBsb3QuZmlnLCBUb2xfU2NvcmVUUF9NNF9TRy5wbG90LmZpZywNCiAgICAgICAgICAgICAgICAgIFRvbF9TeW1fVzJfU0cucGxvdC5maWcsIFRvbF9TeW1fTTFfU0cucGxvdC5maWcsIFRvbF9TeW1fTTRfU0cucGxvdC5maWcsDQogICAgICAgICAgICAgICAgICAgICAgICBucm93PTQsIG5jb2w9MywgYnlyb3c9VFJVRSwNCiAgICAgICAgICAgICAgICAgICAgICAgIHJlbF93aWR0aHM9MSwNCiAgICAgICAgICAgICAgICAgICAgICAgIHJlbF9oZWlnaHRzPWMoMSwgMC44NSwgMC44NSwgMC44NSksIA0KICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzPWMoIkEiLCAiQiIsICJDIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRCIsICJFIiwgIkYiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJHIiwgIkgiLCAiSSIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkoiLCAiSyIsICJMIiksIA0KICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxfc2l6ZT1wYW5lbC5sYWIuc3osIA0KICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxfZm9udGZhY2UgPSAiYm9sZCIpDQoNCiMjU2F2ZSBGaWd1cmUNCmdnc2F2ZShmaWxlbmFtZT0iRmlndXJlcy9GaWd1cmVTMl9Ub2xlcmFuY2VfQWNyb3NzX01ldHJpY3MucG5nIiwgcGxvdD1Ub2xlcmFuY2VfZmlnLCBkcGk9MzAwLCB3aWR0aD0xNCwgaGVpZ2h0PTIwLCB1bml0cz0iaW4iKQ0KDQpgYGANCg0KDQojIyMgRmlndXJlIDQgQ29udHJhc3RzIEhlYXRtYXANCmBgYHtyfQ0KIyNTYXZlIEZpZ3VyZQ0KZ2dzYXZlKGZpbGVuYW1lPSJGaWd1cmVzL0ZpZ3VyZTRfVG9sZXJhbmNlX0hlYXRtYXAucG5nIiwgcGxvdD1Ub2xfUGFpcnMucGxvdCwgZHBpPTMwMCwgd2lkdGg9OCwgaGVpZ2h0PTEyLCB1bml0cz0iaW4iKQ0KDQpgYGANCg0KDQojIFRhYmxlcw0KDQojIyMgVGFibGUgUzIgTGluZWFyIE1vZGVsIFJlc3VsdHMNCmBgYHtyfQ0KIyNDb21iaW5lIFJlc3VsdHMgVGFibGVzDQpUYWJsZVMyX1RvbC5sbS5yZXM8LXJiaW5kKFRvbF9DaGxfVzJfbG0ucmVzLCBUb2xfQ2hsX00xX2xtLnJlcywgVG9sX0NobF9NNF9sbS5yZXMsDQogICAgICAgICAgICAgICAgICAgICAgICBUb2xfU3ltX1cyX2xtLnJlcywgVG9sX1N5bV9NMV9sbS5yZXMsIFRvbF9TeW1fTTRfbG0ucmVzLA0KICAgICAgICAgICAgICAgICAgICAgICAgVG9sX1Njb3JlRl9XMl9sbS5yZXMsIFRvbF9TY29yZUZfTTFfbG0ucmVzLCBUb2xfU2NvcmVGX000X2xtLnJlcywNCiAgICAgICAgICAgICAgICAgICAgVG9sX1Njb3JlVFBfVzJfbG0ucmVzLCBUb2xfU2NvcmVUUF9NMV9sbS5yZXMsIFRvbF9TY29yZVRQX000X2xtLnJlcykNCg0KIyNBZGQgYSBTZWFzb24gVmFyaWFibGUNClRhYmxlUzJfVG9sLmxtLnJlcyRTZWFzb248LWlmZWxzZShUYWJsZVMyX1RvbC5sbS5yZXMkVGltZVA9PSJXMiIsICJTdW1tZXIxIiwgaWZlbHNlKFRhYmxlUzJfVG9sLmxtLnJlcyRUaW1lUD09Ik0xIiwgIlN1bW1lcjIiLCBpZmVsc2UoVGFibGVTMl9Ub2wubG0ucmVzJFRpbWVQPT0iTTQiLCAiV2ludGVyIiAsIE5BKSkpDQoNCiMjT3JnYW5pemUNCm5hbWVzKFRhYmxlUzJfVG9sLmxtLnJlcykNClRhYmxlUzJfVG9sLmxtLnJlczwtVGFibGVTMl9Ub2wubG0ucmVzWyxjKCJUaW1lUCIsICJTZWFzb24iLCAiUmVzcG9uc2UiLCAiUHJlZGljdG9yIiwgIkRGIiwgIlN1bS5TcSIsICJNZWFuLlNxIiwgIkYudmFsdWUiLCAicC52YWx1ZSIsICJFdGFTcSIpXQ0KDQojUm91bmQgdG8gNCBkaWdpdHMNClRhYmxlUzJfVG9sLmxtLnJlcyRTdW0uU3E8LXJvdW5kKFRhYmxlUzJfVG9sLmxtLnJlcyRTdW0uU3EsIDQpDQpUYWJsZVMyX1RvbC5sbS5yZXMkTWVhbi5TcTwtcm91bmQoVGFibGVTMl9Ub2wubG0ucmVzJE1lYW4uU3EsIDQpDQpUYWJsZVMyX1RvbC5sbS5yZXMkRi52YWx1ZTwtcm91bmQoVGFibGVTMl9Ub2wubG0ucmVzJEYudmFsdWUsIDQpDQpUYWJsZVMyX1RvbC5sbS5yZXMkcC52YWx1ZTwtcm91bmQoVGFibGVTMl9Ub2wubG0ucmVzJHAudmFsdWUsIDQpDQpUYWJsZVMyX1RvbC5sbS5yZXMkRXRhU3E8LXJvdW5kKFRhYmxlUzJfVG9sLmxtLnJlcyRFdGFTcSwgNCkNCg0KIyNXcml0ZSBPdXQgVGFibGUNCndyaXRlLmNzdihUYWJsZVMyX1RvbC5sbS5yZXMsICJUYWJsZXMvVGFibGVTMl9Ub2xlcmFuY2VfTE1fUmVzdWx0cy5jc3YiLCByb3cubmFtZXM9RkFMU0UpDQoNCmBgYA0KDQoNCiMjIyBUYWJsZSBTMyBQYWlyd2lzZSBDb21wYXJpc29uIFJlc3VsdHMNCmBgYHtyfQ0KIyNQYWlyd2lzZSBSZXN1bHRzIFRhYmxlDQpUYWJsZVMzX1RvbC5wYWlyd2lzZTwtVG9sX2NvbnRyYXN0cw0KDQojI0FkZCBhIFNlYXNvbiBWYXJpYWJsZQ0KVGFibGVTM19Ub2wucGFpcndpc2UkU2Vhc29uPC1pZmVsc2UoVGFibGVTM19Ub2wucGFpcndpc2UkVGltZVA9PSJXMiIsICJTdW1tZXIxIiwgaWZlbHNlKFRhYmxlUzNfVG9sLnBhaXJ3aXNlJFRpbWVQPT0iTTEiLCAiU3VtbWVyMiIsIGlmZWxzZShUYWJsZVMzX1RvbC5wYWlyd2lzZSRUaW1lUD09Ik00IiwgIldpbnRlciIgLCBOQSkpKQ0KDQojI1JlLW9yZGVyIGJ5IFNlYXNvbmFsIFRpbWVwb2ludA0KVGFibGVTM19Ub2wucGFpcndpc2U8LSBUYWJsZVMzX1RvbC5wYWlyd2lzZSAlPiUgYXJyYW5nZShhcy5udW1lcmljKFRpbWVQKSkNCg0KIyNPcmdhbml6ZQ0KbmFtZXMoVGFibGVTM19Ub2wucGFpcndpc2UpDQpUYWJsZVMzX1RvbC5wYWlyd2lzZTwtVGFibGVTM19Ub2wucGFpcndpc2VbLGMoIlRpbWVQIiwgIlNlYXNvbiIsICJSZXNwb25zZSIsICJDb250cmFzdCIsICJFc3RpbWF0ZSIsICJTRSIsICJkZiIsICJ0LnJhdGlvIiwgInAiKV0NClRhYmxlUzNfVG9sLnBhaXJ3aXNlPC1UYWJsZVMzX1RvbC5wYWlyd2lzZSAlPiUgZHBseXI6OnJlbmFtZSggREYgPSBkZikgJT4lIGRwbHlyOjpyZW5hbWUoIHAudmFsdWUgPSBwKQ0KDQojUm91bmQgdG8gNCBkaWdpdHMNClRhYmxlUzNfVG9sLnBhaXJ3aXNlJEVzdGltYXRlPC1yb3VuZChUYWJsZVMzX1RvbC5wYWlyd2lzZSRFc3RpbWF0ZSwgNCkNClRhYmxlUzNfVG9sLnBhaXJ3aXNlJFNFPC1yb3VuZChUYWJsZVMzX1RvbC5wYWlyd2lzZSRTRSwgNCkNClRhYmxlUzNfVG9sLnBhaXJ3aXNlJHQucmF0aW88LXJvdW5kKFRhYmxlUzNfVG9sLnBhaXJ3aXNlJHQucmF0aW8sIDQpDQpUYWJsZVMzX1RvbC5wYWlyd2lzZSRwLnZhbHVlPC1yb3VuZChUYWJsZVMzX1RvbC5wYWlyd2lzZSRwLnZhbHVlLCA0KQ0KDQojI1dyaXRlIE91dCBUYWJsZQ0Kd3JpdGUuY3N2KFRhYmxlUzNfVG9sLnBhaXJ3aXNlLCAiVGFibGVzL1RhYmxlUzNfVG9sZXJhbmNlX1BhaXJ3aXNlX1Jlc3VsdHMuY3N2Iiwgcm93Lm5hbWVzPUZBTFNFKQ0KYGBgDQoNCg==